INTERCAL (C-INTERCAL), 15 kodlar, 313 + 2 = 315 bayt
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
Çevrimiçi deneyin!
Buradaki tüm boşluklar önemsiz. (Orijinal program sekmeler içeriyordu, ancak onları SE'ye doğru şekilde hizalayacak şekilde boşluklara dönüştürdüm; INTERCAL için 8'lik bir sekme genişliği kullanmak geleneksel. Programın tüm sekmeler, boşluklarla bir sürümünü test ettim. , ve yeni satırlar silindi, ancak iyi çalışıyor.)
Derleme -abm
(2 bayt ceza, çünkü -b
derleyicinin deterministik olması gerekir).
INTERCAL için Her zamanki gibi, bu, örneğin formatında sayısal girdi alır ONE TWO THREE
için 123
.
açıklama
Bir C-INTERCAL programı hata verdiğinde, çıkış durumu modulo 256 hata kodudur. Sonuç olarak, mümkün olduğu kadar çok çalışma zamanı hatası üretebilecek bir program yazmayı hedefleyebiliriz. Bu program yalnızca dahili derleyici sorunlarını göstermeyen iki çalışma zamanı hatası çıkarır: ICL200I, çünkü çoğaltmak yalnızca tek iş parçacıklı bir programla uyumlu olan harici kitaplıkların kullanılmasını gerektirir (ve çok iş parçacıklı programlar daha fazla hata sunar); ve ICL533I, çünkü 533, 277 ile aynı modulo 256 değerine sahiptir ve program, ICL277I üretme kapasitesine sahiptir.
Program her zaman aynı şekilde başlar. İlk önce, WRITE IN
değişken için bir değer ( ) giriyoruz .1
. Daha sonra, CREATE
yeni bir sözdizimi oluşturmak için hesaplanmış bir ifade kullanırız (burada, A
); ancak hesaplandığı için, sözdiziminin tanımı, değerine göre değişir .1
. Son olarak, çoğu durumda A
, bir hata üretmek için tanımlanmış olan yeni ifademizi çalıştırırız ; Sahip olduğumuz olası tanımların tablosu, her olası çalışma zamanı hatası için bir tanım içerir (yukarıda belirtilen istisnalar dışında).
İlk olarak, bu genel şema için iki istisna vardır. (0)
geçerli bir satır numarası değildir, bu nedenle kullanıcı girerse, ZERO
ikinci bir satırdan (numaralı (8)
) dördüncü satıra bir hesaplamalı COME FROM
ifade ile atlarız . Bu daha sonra hata DO X
üreten bir sözdizimi hatası içine düşer ICL000I
. (INTERCAL'de, devre dışı bırakma komutları, sizin altınızda yeniden tanımlanacak sözdizimi vb. Nedeniyle çalışma zamanında sözdizimi hataları oluşur.) COME FROM
Açıklamada ayrıca gerçek bir olsa bile, bir yan etkisi vardır COME FROM
bir işlenen aşırı oluşturma olur .1
için #1
bir hat numarası ile bir çizgi yürütülen her; bu, daha sonra 21 çıktı üretilirken kullanılır. (Rastgele global yan etkiler INTERCAL'de oldukça deyimseldir.)
Diğer istisna da girdiyledir ONE TWO NINE
. (129)
Programda satır numarası yok , bu yüzden eksik olan bir satır numarası için bir hata alıyoruz ICL129I
. Bu yüzden bu davayı ele almak için herhangi bir kod yazmak zorunda değildim.
İşte diğer hatalar ve bunlara sebep olan:
- 123 bir
NEXT
yığın taşmasıdır ( DO (123) NEXT
). NEXT
Beyanı (diğer değiştiricileri ihtiyacı FORGET
veya RESUME
geriye dönük ne olduğunu kontrol ifadesinin tür belirlemek amacıyla). Bunlara sahip olmamak, ICL123I hatasında bir kez 80 çözülmemiş `NEXT ifadesi var.
- 222 bir stash taşması (
DO STASH .2
bir COME FROM
döngüde). Zımbalar sadece mevcut hafıza ile sınırlıdır, fakat sonuçta tükenir, bu da ICL222I hatasına neden olur.
- 240 , sıfıra eşit bir dizidir. Bu tam olarak ne
DO ,1 <- #0
anlama geliyor ve ICL240I hatasına neden oluyor.
- 241 , bir dizinin sınırları dışına atanmaktan kaynaklanır. Bu durumda
,1
tahsis edilmedi ( ,
INTERCAL'deki dizi tipi değişkenler için kullanılır), bu nedenle indeksleme ICL241I hatasına neden olur.
- 19 , 65536 (
#256 $ #0
) yöntemini 16 bitlik bir değişkene atar .2
. Uygun değil, ICL275I hatasına neden oluyor.
- 21 atar
#2
etmek .1
. Bu, yeterince basit bir atamaya benzeyebilir, ancak daha önce .1
kastetmek için aşırı yükledik ve komut satırında #1
hiçbir -v
seçenek olmadan 1 değerini değiştirmeye çalışmak ICL277I hatasına neden oluyor.
- 148
GO BACK
, programın bu noktasında bulunmayan choicepoint yığınının ( ) üst girişine geri dönmeye çalışır (choicepoint yığını işlemek için herhangi bir komut çalıştırmadık, bu yüzden hala boştur). Bu ICL404I hatasına neden olur.
- 180
RETRIEVE .2
, varolmayan bir zulaya teşebbüs eder (çünkü programın bu bölümünde hiçbir şeyi saklayamadık), ICL436I hatasına neden oldu.
- 50
WRITE IN
sonsuza kadar bir COME FROM
döngü içinde input ( ) ister . Sonunda EOF'yi okuduktan sonra ICL562I hatasına neden olacağız.
- 109
DO RESUME #0
, anlamsız ve özellikle bir hataya neden olduğu belgelenen ifadeyi çalıştırmaktadır (ICL621I).
- 120 deyimi çalıştırır
DO RESUME #9
. NEXT
Henüz bu kadar fazla ifade kullanmadık ve bu nedenle ICL120I hatası alıyoruz. (Şaşırtıcı bir şekilde, bu özel hata INTERCAL belgelerinde programdan normal bir şekilde çıkılması ve daha sonra bir hatayla programdan çıkılması yerine hataya neden olmasıyla tanımlanır.
- 223 temel olarak hepsi hat 223'ü işaret eden ve hafızayı patlatan sonsuz bir döngüye neden olan çok iş parçacıklı ilkellerin karışıklığıdır. Sonunda, çok iş parçacıklı alt sistemde bellek tükenmesi var ve bu da ICL991I hatasına neden oluyor.
- 121 aslında geçerli bir ifade (yorum), ancak programın sonunda beliriyor. Bu nedenle, yürütme yürütüldükten hemen sonra programın sonundan düşer ve bu da ICL633I hatasına neden olur.
Doğrulama
Bazı hatalar kasıtlı olarak programın belleğinin dışında çalışılmasını içerir, bu yüzden oldukça küçük bellek limitleri ayarlamayı öneririm. İşte programı test etmek için kullandığım shell komutu (okunabilirlik için yeni satırlar eklenmiş; kendiniz çalıştırıyorsanız silin):
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
Ve burada çıktı (alan numaralarını silmek için silinen satır satırları ve "LÜTFEN KAYNAK KAYNAKLARI" mesajları ile silinmiş), ki programın çalıştığını göstermek için kısmen ekledim, fakat INTERCAL'in saçma hata mesajlarını göstermek için:
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