INTERCAL (C-INTERCAL), 15 Codes, 313 + 2 = 315 Bytes
PLEASE WRITE IN .1
(8) PLEASE CREATE .1 A
PLEASE A
PLEASE COME FROM #2$!1/#1'
DO X
(123) DO (123) NEXT
DO COME FROM (222)
(222) DO STASH .2
(240) DO ,1 <- #0
(241) DO ,1 SUB #0 <- #1
(19) DO .2 <- #256 $ #0
(21) DO .1 <- #2
(148) DO GO BACK
(180) DO RETRIEVE .2
DO COME FROM (50)
(50) DO WRITE IN .2
(109) DO RESUME #0
(120) DO RESUME #9
MAYBE COME FROM (223)
(223) DO COME FROM (223)
(121) PLEASE NOT X
Probieren Sie es online!
Alle Leerzeichen sind hier irrelevant. (Das ursprüngliche Programm enthielt Tabulatoren, aber ich habe sie in Leerzeichen konvertiert, damit sie in SE korrekt ausgerichtet sind. Es ist üblich, für INTERCAL eine Tabulatorenbreite von 8 zu verwenden. Ich habe eine Version des Programms mit allen Tabulatoren und Leerzeichen getestet , und Zeilenumbrüche gelöscht, und es funktioniert gut.)
Kompilieren Sie mit -abm
(2-Byte-Strafe, da -b
der Compiler deterministisch sein muss).
Wie üblich für INTERCAL, nimmt diese numerische Eingabe in das Format, zB ONE TWO THREE
für 123
.
Erläuterung
Wenn ein C-INTERCAL-Programm ausfällt, ist der Exit-Status der Fehlercode modulo 256. Als Ergebnis können wir versuchen, ein Programm zu schreiben, das in der Lage ist, so viele Laufzeitfehler wie möglich zu erzeugen. Dieses Programm lässt nur zwei Laufzeitfehler aus, die keine internen Compilerprobleme anzeigen: ICL200I, da für die Reproduktion externe Bibliotheken erforderlich sind, die nur mit einem Single-Thread-Programm kompatibel sind (und bei Multithread-Programmen sind mehr Fehler verfügbar). und ICL533I, da 533 den gleichen Wert modulo 256 wie 277 hat und das Programm ICL277I erzeugen kann.
Das Programm startet immer auf die gleiche Weise. Zuerst geben wir ( WRITE IN
) einen Wert für die Variable ein .1
. Dann verwenden wir eine berechnete CREATE
Anweisung, um eine neue Syntax zu erstellen (hier, A
). Da die Syntax berechnet wird, hängt sie vom Wert von ab .1
. Schließlich führen wir in den meisten Fällen unsere neue A
Anweisung aus, die als fehlerhaft definiert wurde. Die Tabelle der möglichen Definitionen enthält eine Definition für jeden möglichen Laufzeitfehler (mit Ausnahme der oben aufgeführten Ausnahmen).
Erstens gibt es zwei Ausnahmen von diesem allgemeinen Schema. (0)
ist keine gültige Zeilennummer. Wenn der Benutzer also etwas eingibt ZERO
, springen wir (8)
mithilfe einer berechneten COME FROM
Anweisung von der zweiten (nummerierten ) zur vierten Zeile . Dies führt dann zu einem Syntaxfehler DO X
, der zu Fehlern führt ICL000I
. (In INTERCAL treten zur Laufzeit Syntaxfehler auf, die auf die Tendenz zurückzuführen sind, Befehle zu deaktivieren, die Syntax unter Ihnen neu zu definieren usw.). Die COME FROM
Anweisung hat auch dann eine Nebenwirkung, wenn kein tatsächliches COME FROM
Ereignis eintritt. Sie erzeugt eine Operandenüberladung von .1
bis, #1
wenn eine Zeile mit einer Zeilennummer ausgeführt wird. Dies wird später bei der Ausgabe von 21 verwendet. (Zufällige globale Nebenwirkungen sind in INTERCAL ziemlich idiomatisch.)
Die andere Ausnahme betrifft die Eingabe ONE TWO NINE
. Das (129)
Programm enthält keine Zeilennummer , daher erhalten wir eine Fehlermeldung für eine fehlende Zeilennummer ICL129I
. Ich musste also überhaupt keinen Code schreiben, um diesen Fall abzudecken.
Hier sind die anderen Fehler und deren Ursachen:
- 123 ist ein
NEXT
Stapelüberlauf ( DO (123) NEXT
). Die NEXT
Anweisung benötigt andere Modifikatoren ( FORGET
oder RESUME
), um rückwirkend zu bestimmen, um welche Art von Steueranweisung es sich handelt. Wenn diese nicht vorhanden sind, wird der Fehler ICL123I ausgelöst, sobald 80 ungelöste `NEXT-Anweisungen vorliegen.
- 222 ist ein Stash-Überlauf (
DO STASH .2
in einer COME FROM
Schleife). Die Stashes sind nur durch den verfügbaren Speicher begrenzt, aber dieser wird irgendwann ausgehen und den Fehler ICL222I verursachen.
- 240 ist Dimensionen ein Array mit der Größe Null. Genau das
DO ,1 <- #0
bedeutet, und es verursacht den Fehler ICL240I.
- 241 wird durch Zuweisen außerhalb der Grenzen eines Arrays verursacht. In diesem Fall
,1
wurde keine Zuordnung vorgenommen ( ,
wird für Variablen vom Typ Array in INTERCAL verwendet). Die Indizierung verursacht daher den Fehler ICL241I.
- 19 weist
#256 $ #0
einer 16-Bit-Variablen 65536 ( ) zu .2
. Es passt nicht und verursacht den Fehler ICL275I.
- 21 ordnet
#2
an .1
. Das sieht vielleicht einfach aus, aber wir haben es überladen .1
, um es #1
früher zu meinen , und der Versuch, den Wert 1 ohne -v
Option in der Befehlszeile zu ändern , verursacht den Fehler ICL277I.
- 148 Versuche, zum obersten Eintrag des Auswahlpunktstapels (
GO BACK
) zurückzukehren, der zu diesem Zeitpunkt im Programm noch nicht vorhanden ist (wir haben keine Befehle zum Bearbeiten des Auswahlpunktstapels ausgeführt, daher ist dieser noch leer). Das verursacht Fehler ICL404I.
- 180 Versuche
RETRIEVE .2
von einem nicht existierenden Stash (weil wir dort nichts in diesem Zweig des Programms versteckt haben), was den Fehler ICL436I verursacht.
- 50 Requests input (
WRITE IN
) für immer in einer COME FROM
Schleife. Irgendwann werden wir nach dem EOF lesen und den Fehler ICL562I verursachen.
- 109 führt die Anweisung aus
DO RESUME #0
, die bedeutungslos und spezifisch als fehlerverursachend dokumentiert ist (ICL621I).
- 120 führt die Anweisung aus
DO RESUME #9
. Wir haben noch nicht so viele NEXT
Anweisungen ausgeführt und erhalten daher den Fehler ICL120I. (Interessanterweise wird dieser bestimmte Fehler in der INTERCAL-Dokumentation so definiert, dass er das Programm normal beendet und dann den Fehler verursacht, anstatt das Programm mit einem Fehler zu beenden. Ich glaube jedoch nicht, dass diese beiden Fälle sich merklich unterscheiden.)
- 223 ist im Grunde ein komplexes Gewirr von Multithreading-Grundelementen, die alle auf Zeile 223 verweisen und eine Endlosschleife verursachen, die den Speicher in die Luft sprengt. Möglicherweise ist der Speicher im Multithreading-Subsystem erschöpft, was zum Fehler ICL991I führt.
- 121 ist eigentlich eine gültige Aussage (es ist ein Kommentar), aber sie erscheint am Ende des Programms. Daher fällt die Ausführung unmittelbar nach der Ausführung des Programms vom Programmende ab, wodurch der Fehler ICL633I verursacht wird.
Nachprüfung
Einige der Fehler bestehen darin, dass das Programm absichtlich nicht genügend Arbeitsspeicher hat. Ich empfehle daher, relativ kleine Arbeitsspeicherlimits festzulegen. Hier ist der Shell-Befehl, den ich zum Testen des Programms verwendet habe (mit Zeilenumbrüchen, die der Lesbarkeit halber hinzugefügt wurden; löschen Sie sie, wenn Sie sie selbst ausführen):
for x in "ZERO" "ONE NINE" "TWO ONE" "FIVE ZERO" "ONE ZERO NINE"
"ONE TWO ZERO" "ONE TWO ONE" "ONE TWO THREE" "ONE TWO NINE"
"ONE FOUR EIGHT" "ONE EIGHT ZERO" "TWO TWO TWO"
"TWO TWO THREE" "TWO FOUR ZERO" "TWO FOUR ONE";
do echo;
echo $x;
echo $x | (ulimit -Sd 40000; ulimit -Sv 40000; ulimit -Ss 40000;
./errors; echo $?);
done
Und hier ist die Ausgabe (mit den Zeilennummern und "BITTE KORREKTURIEREN" -Nachrichten, die aus Platzgründen gelöscht wurden), die ich teilweise hinzugefügt habe, um die Funktionsweise des Programms zu demonstrieren, aber hauptsächlich, um die albernen Fehlermeldungen von INTERCAL zu demonstrieren:
ZERO
ICL000I PLEASEWRITEIN.1(8)PLEASECREATE.1APLEASEAPLEASECOMEFROM#2$!1/#1'DOX(123)DO(123)NEXTDOCOMEFROM(222)(222)DOSTASH.2(240)DO,1<-#0(241)DO,1SUB#0<-#1(19)DO.2<-#256$#0(21)DO.1<-#2(148)DOGOBACK(180)DORETRIEVE.2DOCOMEFROM(50)(50)DOWRITEIN.2(109)DORESUME#0(120)DORESUME#9MAYBECOMEFROM(223)(223)DOCOMEFROM(223)(121)PLEASENOTX
0
ONE NINE
ICL275I DON'T BYTE OFF MORE THAN YOU CAN CHEW
19
TWO ONE
ICL277I YOU CAN ONLY DISTORT THE LAWS OF MATHEMATICS SO FAR
21
FIVE ZERO
ICL562I I DO NOT COMPUTE
50
ONE ZERO NINE
ICL621I ERROR TYPE 621 ENCOUNTERED
109
ONE TWO ZERO
ICL632I THE NEXT STACK RUPTURES. ALL DIE. OH, THE EMBARRASSMENT!
120
ONE TWO ONE
ICL633I PROGRAM FELL OFF THE EDGE
121
ONE TWO THREE
ICL123I PROGRAM HAS DISAPPEARED INTO THE BLACK LAGOON
123
ONE TWO NINE
ICL129I PROGRAM HAS GOTTEN LOST
129
ONE FOUR EIGHT
ICL404I I'M ALL OUT OF CHOICES!
148
ONE EIGHT ZERO
ICL436I THROW STICK BEFORE RETRIEVING!
180
TWO TWO TWO
ICL222I BUMMER, DUDE!
222
TWO TWO THREE
ICL991I YOU HAVE TOO MUCH ROPE TO HANG YOURSELF
223
TWO FOUR ZERO
ICL240I ERROR HANDLER PRINTED SNIDE REMARK
240
TWO FOUR ONE
ICL241I VARIABLES MAY NOT BE STORED IN WEST HYPERSPACE
241