Forum moved to if-forum.org
Autor Nachricht
<  Compiler-Probleme mit Infix
ChristianB
BeitragVerfasst am: Do, 1 Jun 2006 - 14:59  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg

Hallo, Inform-Profis,

ich möchte die Infix-Verben benutzen und habe sie mit !% -X nebst !% $MAX_LABELS=1500 eingebunden (der Default von 1000 war zu klein und der Compiler hat das auch entsprechend angemeckert und einen Vorschlag zur Abhilfe gegeben). Leider funktioniert Infix hier jetzt nur im Nicht-Strict-Mode, wenn der Strict-Mode aktiviert ist, dann bekomme ich folgende Fehlermeldung:

Inform 6.31 hat folgendes geschrieben:
<veneer routine 'RT__ChPrintO'>(1): Fatal Error: Branch out of range:
divide routine up?

Ich benutze den Compiler Inform 6.31, bei 6.30 gab es aber dasselbe Problem. Mein Quelltext ist zurzeit 119 K groß inklusive der eingebundenen Erweiterungen, dazu kommen noch die aktuellen deform-Libs. Woran kann es liegen, und wie komme ich trotzdem noch in den Genuss der Infix-Verben im Strict-Modus? Wer weiß es, wer weiß es?

Viele Grüße, CB
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Sophie
BeitragVerfasst am: Fr, 2 Jun 2006 - 22:23  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 06.06.2005
Beiträge: 59
Wohnort: 46° 38' N 14° 20' O

Hi Christian,

Ich hab da keine Probleme. Ich hab es mit folgenden Switches versucht:

Code:
!% +include_path=/boot/develop/inform/def611
!% -XDSds
!% -v8
!% $MAX_VERBS=200
!% $MAX_LABELS=1200
!% $MAX_EXPRESSION_NODES=224

Meine Dateien haben insgesamt 384125 Bytes:

Code:
$ls -l
total 812
-rw-r--r--   1 monkey   apes     3901 Dec 12 23:46 marray.h
-rw-rw-rw-   1 monkey   apes   317462 Jun  2 22:49 inseln.inf
-rw-r--r--   1 monkey   apes    48086 May 28 00:01 kapitel5.inf
-rw-r--r--   1 monkey   apes     7852 Jan  8 21:05 phredoo.h
-rw-r--r--   1 monkey   apes     6824 May 28 20:48 unterwasser.inf

Zu groß kanns also nicht sein.

Und die Compilerstatistik schaut aus wie folgt:

Code:
$make
cp *.inf ../inseln_bak/
inform inseln.inf
Inform 6.31 for BeOS (10th Feb 2006)
In: 13 source code files             17585 syntactic lines
 23186 textual lines                892522 characters (ISO 8859-1 Latin1)
Allocated:
  1883 symbols (maximum 6400)     1075379 bytes of memory
Out:   Version 8 "Extended" story file 1.060602 (421K long):
    18 classes (maximum 64)          316 objects (maximum 511)
   153 global vars (maximum 233)    4641 variable/array space (maximum 10000)
   159 verbs (maximum 200)          1151 dictionary entries (maximum 1300)
   584 grammar lines (version 2)    1489 grammar tokens (unlimited)
   158 actions (maximum 200)          32 attributes (maximum 48)
    56 common props (maximum 62)      58 individual props (unlimited)
291914 characters used in text    235876 bytes compressed (rate 0.808)
     0 abbreviations (maximum 64)    977 routines (unlimited)
 37974 instructions of Z-code      11528 sequence points
 41704 bytes readable memory used (maximum 65536)
430624 bytes used in Z-machine     93664 bytes free in Z-machine
Completed in 1 seconds

(Das ist ein bisschen unschön formatiert.)

Hast du es schon mit -v8 versucht? Obwohl man da eine andere Meldung kriegt, wenn v5 nicht mehr ausreicht. Kurz gesagt, keine Ahnung. ;-) (Übrigens hab ich normalerweise nur -X, und D und S nicht aktiviert, D ist automatisch dabei, und S weiß ich nicht.)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ChristianB
BeitragVerfasst am: Di, 6 Jun 2006 - 21:10  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg

Hallo, Sophie,

vielen Dank für deine Tipps. Ich habe alles durchprobiert und letzten Endes festgestellt, dass es nicht an den Switches liegt.

Denn wenn ich mindestens eines der Arrays CompoundHeads oder CompundTails verwende, dann gibt es die oben beschriebene Fehlermeldung. Mit dem Synonyms-Array funktioniert es. Aber schon ein einziger Eintrag in CompundHeads oder -Tails, z.B.

Code:
 Array CompoundHeads table
    "stahl"     0
    ;

reicht aus, um den Compiler in Hinblick auf Infix im Strict-Mode zu verwirren. Ist doch seltsam.

Grüße, CB
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Martin
BeitragVerfasst am: Mi, 7 Jun 2006 - 7:26  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 25.08.2002
Beiträge: 677
Wohnort: München

ChristianB hat folgendes geschrieben:
Ist doch seltsam.

Allerdings. An der Definition des Feldes kann es nicht liegen, denn obwohl die Compound-Felder Mischfelder (d.h. Felder mit gemischten Datentypen) sind, sind sie doch für Inform ein ganz normales Feld.

Je nachdem, ob die Compound-Felder definiert sind oder nicht, wird allerdings Code kompiliert oder nicht, das passiert mit #ifdefs in German.h.

Die RT__*-Routinen gehören zur Runtime Veneer. Das sind unsichtbare Routinen, die im strikten Modus zusätzliche Abfragen einbauen um zu verhindern, dass die z-Maschine abstürzt. Die Zeile
Code:

     x = 2 / y;

würde also im strikten Mosus nicht in die z-Code-Anweisung
Code:

    @div 2 x -> x;

übersetzt, sondern in eine Runtime-Routine, die dann etwa so aussehen könnte:
Code:

    [ RT__Divide x y;
        if (y == 0) {
            print "[*** Programming Error:
                Division by Zero. ***]^";
            return 0;
        }
        @div x / y -> sp;
        @ret_popped;
    ];

In dieser Routine wird also überprüft, ob der Nenner Null ist. Im strikten Modus kommt dann der Programmfehler, das Programm läuft dann aber weiter. Im laxen (oder wie der nicht-strikte Modus heißt) Modus würde es einen Laufzeitfehler in der z-Maschine geben, der zum Abruch des Spiels führt.

Neben arithmetischen Funktionen @div und @mod wird beim Feldzugriff mit -> und --> und bei Routinen für Objekte mit Runtime-Veneer-Routinen gearbeitet. Bei den Anweisungen für Objekte ist es meist illegal nothing anstelle eines Objekts zu übergeben, weil, wie das DM4 nicht müde wird zu betonen, nothing kein Objekt ist. (Was ein bisschen blöd ist. Wieso kann ich zum Beispiel nicht "move apple to nothing" sagen, sondern muss "remove apple" benutzen?)

Die Routine RT__ChPrintO() wird bei der Ausgabe des Objektnamens mit (object) verwendet. Diese Printing Rule gibt den String aus, der im Kopf eines Objekts als Name definiert wurde.

Eigenartigerweise wird diese Regel innerhalb der Compound-#ifdefs nicht benutzt, und sie kommt auch woanders vor, zum Beispiel in PSN__ (Print Short Name). Auch kann ich nicht erkennen, dass in den Compound-Blöcken irgend eine anderes Feature verwendet wird, das woanders nicht vorkommt.

Meine Vermutung ist nämlich: Durch das Einbinden von CompoundHeads bzw. -Tails wird irgendeine Runtime-Routine definiert, die dann das ganze Runtime-System durcheinanderbringt. In einem Programm, in dem "(object) x" nicht vorkommt, muss auch keine Routine RT__ChPrintO im Runtime Veneer definiert werden, genauso für jedes andere Feature.

Die einzige Syntax, bei der ich mir vorstellen kann, dass innerhalb der Compound-Blöcke RT-Routinen erzeugt werden, sind die Lesezugriffe auf das Feld mit -->. Aber das ist nicht Neuses, denn dass wird bereits an x Stellen getan, auch für tables. (Ich kann mir denken, dass tables, strings, ->, --> und Buffer verschiedene RT-Routinen haben.)

Routinen, die aus dem Block heraus aufgerufen werden, wie LTI_Insert oder Tokenise__ können eigentlich nichts damit zu tun haben, denn sie wurden ja bereits erfolgreich definiert.

Dass es bei den Synonymen keinen Unterschied macht, liegt daran, dass der Synonymcode in jedem Fall erzeugt wird, da es bereits vordefinierte Synonyme gibt ("ins", "am" usw.).

Okay, viel geschrieben, nichts erreicht. Aber vielleicht gibt dir das ja einen Hinweis. (Wenn du möchtest, kannst du einmal Compound-Heads definieren und Stück für Stück Zeilen aus dem Block #ifdef CompoundHeads auskommentieren. Vielleicht bringt uns das weiter.)
_________________
Every silver lining has a cloud.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
ChristianB
BeitragVerfasst am: Do, 8 Jun 2006 - 11:50  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg

Martin, vielen Dank. Mit den die CompoundHeads- und –Tails betreffenden #Ifdef-Blöcken in German.h scheint es nicht unmittelbar etwas zu tun zu haben. Ich habe dann meinen Code nach und nach verkleinert und irgendwann war ein Punkt erreicht, an dem alles wieder normal funktionierte. Es spielte dabei keine Rolle, welche Art Code man herausnimmt, Objekte, Routinen, Verben etc., es scheint lediglich um die Datenmenge zu gehen (im Quelltext oder in der vom Compiler erzeugten Datei?). Wenn sich der Code gerade mal so eben mit Infix im Strict Mode compilieren lässt, dann ist die erzeugte Spieldatei 196 KB groß, also verdächtig nah an 200. Ist das vielleicht ein Limit für oder von irgendetwas, das auch in v8 noch gilt?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Martin
BeitragVerfasst am: Do, 8 Jun 2006 - 13:58  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 25.08.2002
Beiträge: 677
Wohnort: München

ChristianB hat folgendes geschrieben:
Ich habe dann meinen Code nach und nach verkleinert und irgendwann war ein Punkt erreicht, an dem alles wieder normal funktionierte. Es spielte dabei keine Rolle, welche Art Code man herausnimmt, Objekte, Routinen, Verben etc., es scheint lediglich um die Datenmenge zu gehen (im Quelltext oder in der vom Compiler erzeugten Datei?)
Hmmm. Ich vermute, dass Infix für jede Datenstruktur im Programm (Objekt, Klasse, Feld, usw.) eigene Daten erzeugt, und so das Spiel einfach schneller wächst. Außerdem muss ja auch irgendwo noch der Parser für die Inform-Syntax hineinpassen. Und die Break- und Watchpoints für den Debugger.

ChristianB hat folgendes geschrieben:
Wenn sich der Code gerade mal so eben mit Infix im Strict Mode compilieren lässt, dann ist die erzeugte Spieldatei 196 KB groß, also verdächtig nah an 200. Ist das vielleicht ein Limit für oder von irgendetwas, das auch in v8 noch gilt?
Nein. Das absolute Limit für v5 sind 256, für v8 512 Kilobyte. Was aber Probleme bereiten könnte, ist die Größes des dynamischen Speichers, also des Speichers, der mit Inform-Zahlen addressierbar ist, und der muss kleiner sein als 64 KB oder 65536 Bytes. In diesem Bereich sind alle Objektdefinitionen, globale Variablen, Felder und auch das Wörterbuch abgelegt.

Alles was nach dem dynamischen Speicher in der Spieldatei folgt, sind Routinen und Texte, die nicht direkt durch Inform-Zahlen referenziert werden. (Sondern durch 4 bzw. 8 mal eine Inform-Zahl. So ergeben sich die absoluten Limits von 4 * 64K (256, v5) und 8 * 64K (512K, v8). "Dynamischer Speicher" ist auch nicht das richtige Wort, denn ein Teil des mit 16-Bit-Zahlen adressierbaren Speichers ist statisch, wie zum Beispiel das Wörterbuch.)

Abschnitt 45 im DM2 beschreibt einige Strategien, um Daten aus dem dynamischen Speicherbereich auszulagern.

Du kannst einmal deine Kompilationen mit und ohne Infix mit der Option -z laufen lassen. Diese Option druckt dir eine Memory Map aus, die genau zeigt, welcher Bereich der Spieldatei - Objekte, Objekteigenschaften, Felddefinitionen, usw. - wieviel Speicher benötigt. Im direkten Vergleich müsste man doch sehen können, wo Infix draufschlägt. (Du solltest aber keine Angst vor Hexadezimalzahlen haben :-)

Einen Überblick über den Speicherhunger von Inform in verschiedenen Modi gibt es im Inform FAQ, eine Übersicht über die Debug-Optionen in InfLight.
_________________
Every silver lining has a cloud.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Sophie
BeitragVerfasst am: Do, 8 Jun 2006 - 18:34  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 06.06.2005
Beiträge: 59
Wohnort: 46° 38' N 14° 20' O

Ich hab einmal so zum Spaß versucht, den zitierten Code mit CompoundHeads in meine Datei einzufügen, aber wie ihr ja schon festgestellt habt, macht das keinen Unterschied.

An der Größe kann's wie gesagt wohl kaum liegen, denn meine Spieldatei ist über 400k groß.

Wegen limits, verwende -s, dann bekommst du so eine Statistik, wie ich sie oben zitiert habe, da kannst du auch sehen, wieviel readable memory verwendet wird. Aber ich nehme an, wenn das nicht ausreicht, wird der Compiler das wohl sagen.

Hast du schon versucht, nachdem du jetzt stückweise Code rausgenommen hast, ihn wieder stückweise reinzugeben? Oder ist es egal, was du dazugibst, und es funktioniert nicht mehr?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ChristianB
BeitragVerfasst am: Fr, 9 Jun 2006 - 15:41  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg

Ich blick nicht mehr durch: es kommt doch darauf an, was ich aus dem Code herausnehme. Ich bin jetzt an einem Punkt angelangt, wo alles bestens funktioniert. Wenn ich auch nur eine kleine Mini-Routine hinzufüge, dann geht’s nicht mehr. Aber die Anzahl der Routinen ist doch unbegrenzt, wenn ich das richtig verstanden habe, oder nicht?

Hier mal die Statistik (vorsichtshalber in v8) von dem Zustand, wo noch alles in Butter ist.

Code:
 Inform 6.31 for Win32 (10th Feb 2006)
[Including EZDOORS]
[Including NEWLIB]
[Including LOCKSMITH]
[Including SMARTCANTGO]
[Including NEWVERBS]
In: 14 source code files             14936 syntactic lines
 18351 textual lines                622881 characters (ISO 8859-1 Latin1)
Allocated:
  1706 symbols (maximum 10000)       1013003 bytes of memory
Out:   Version 8 "Extended" story file 1.060609 (241K long):
    16 classes (maximum 64)            106 objects (maximum 639)
   158 global vars (maximum 233)      4500 variable/array space (maximum 10000)
   172 verbs (maximum 200)            1065 dictionary entries (maximum 2000)
   686 grammar lines (version 2)      1831 grammar tokens (unlimited)
   172 actions (maximum 500)            35 attributes (maximum 48)
    57 common props (maximum 62)        57 individual props (unlimited)
 89663 characters used in text       80992 bytes compressed (rate 0.903)
     0 abbreviations (maximum 64)      696 routines (unlimited)
 32738 instructions of Z-code         9321 sequence points
 32080 bytes readable memory used (maximum 65536)
246368 bytes used in Z-machine      277920 bytes free in Z-machine
Completed in 0 seconds

So. Und wenn ich jetzt mal testhalber so etwas wie

Code:
[ InformDoesntLikeMe;
    print_ret "Keiner hat mich lieb.";
];

im Code hinzufüge, dann bringt das Informs Hormonhaushalt total durcheinander. Ich geb’s auf. Vielen Dank für Eure Mühe!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Sophie
BeitragVerfasst am: Sa, 10 Jun 2006 - 12:39  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 06.06.2005
Beiträge: 59
Wohnort: 46° 38' N 14° 20' O

Ja, die Anzahl der Routinen ist nicht nur unbegrenzt, du hast auch weniger als ich.

Ich glaub, die einzige Möglichkeit, herauszufinden, was nicht passt, ist, inform mit asm_trace_level = 4 zu kompilieren, und dann zu schauen, an welcher Routine es scheitert.

Wenn das bei dir nicht geht, kannst du mir gerne deinen Quellcode schicken, und ich könnte nachschauen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Sophie
BeitragVerfasst am: Sa, 10 Jun 2006 - 13:00  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 06.06.2005
Beiträge: 59
Wohnort: 46° 38' N 14° 20' O

Ich seh grad, das geht auch mit 'inform -a' für asm_trace_level 1 und 'inform -t' für asm_trace_level 2, aber interessant wird's erst bei 4.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ChristianB
BeitragVerfasst am: Mi, 14 Jun 2006 - 10:29  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg

Vor uns haben sich schon andere mit dieser seltsamen Fehlermeldung beschäftigt:

http://www.inform-fiction.org/patches/C63003.html

Der Lösungsvorschlag übersteigt allerdings meine momentanen Möglichkeiten.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Sophie
BeitragVerfasst am: Mi, 14 Jun 2006 - 10:47  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 06.06.2005
Beiträge: 59
Wohnort: 46° 38' N 14° 20' O

Ah, das ist gut zu wissen. Ich hab mir schon gedacht, dass das Problem ganz wo anders liegt, als es aussieht.

Jetzt musst du nur noch jemanden finden, der dir Inform mit dieser Änderung neu kompiliert, wenn du das selber nicht kannst. Ich hab leider nur so einen cygwin-Compiler. Ich glaub, da brauchst du cygwin für alles, was man mit dem kompiliert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
ChristianB
BeitragVerfasst am: Do, 15 Jun 2006 - 13:36  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 05.05.2004
Beiträge: 633
Wohnort: Hamburg

Tja, mein C-Compiler und ich, wir haben uns schon lange nicht mehr sehr weit weg vom Hallo-Welt-Niveau bewegt, aber ich denke ich krieg das hin, jetzt nachdem ich mir den Patch genauer angesehen habe...

Nochmals ein großes Dankeschön.

Edit: Prima Patch! Jetzt funktioniert alles.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Alle Zeiten sind GMT + 1 Stunde (MEZ)

Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Seite 1 von 1
if-de :: Forum Foren-Übersicht  >  Inform & Glulx

Neues Thema eröffnen   Neue Antwort erstellen


 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.



Kontakt: Administrator

Powered by phpBB and NoseBleed v1.05