Clem, birinci sınıf işlevlere sahip minimal yığın tabanlı bir programlama dilidir. Amacınız Clem dili için bir tercüman yazmaktır. Düzgün kullanılabilir referans uygulanması dahil tüm örneklerini yürütmek gerekir burada .
- Her zamanki gibi standart boşluklar uygulanır.
- En küçük bayt sayımı kazanır.
Clem dili
Clem, birinci sınıf işlevlere sahip yığın tabanlı bir programlama dilidir. Clem'i öğrenmenin en iyi yolu, clem
yorumlayıcıyı argüman olmadan çalıştırmaktır . Kullanılabilir komutlarla oynamanıza izin veren etkileşimli modda başlayacaktır. Örnek programları çalıştırmak için şunu yazın: clem example.clm
example, programın adıdır. Bu kısa eğitici, başlamanız için yeterli olmalıdır.
İki ana işlev sınıfı vardır. Atom fonksiyonları ve bileşik fonksiyonlar. Bileşik fonksiyonlar, diğer bileşik fonksiyonlardan ve atom fonksiyonlarından oluşan listelerdir. Bileşik bir işlevin kendisini içeremeyeceğini unutmayın.
Atomik Fonksiyonlar
İlk atomik fonksiyon tipi sabittir . Bir sabit , sadece bir tamsayı değerdir. Örneğin, -10. Yorumlayıcı bir sabitle karşılaştığında , onu yığına doğru iter. clem
Şimdi koş . Tip -10
istemi de. Görmelisin
> -10
001: (-10)
>
Değer 001
yığınında fonksiyonun konumunu açıklar ve (-10)
bir sabit sadece girdi. Şimdi +11
bilgi istemine girin . Görmelisin
> +11
002: (-10)
001: (11)
>
Uyarı (-10)
yığındaki ikinci pozisyona taşındığı ve (11)
şimdi ilk kaplar. Bu bir yığının doğasıdır! Bunun -
da azalma komutu olduğunu göreceksiniz . Ne zaman -
ya da +
bir numara önüne, o sayının işaretini olup ilgili komutu belirtir. Diğer tüm atom fonksiyonları komuttur . Toplam 14 adet var:
@ Rotate the top three functions on the stack
# Pop the function on top of the stack and push it twice
$ Swap the top two functions on top of the stack
% Pop the function on top of the stack and throw it away
/ Pop a compound function. Split off the first function, push what's left,
then push the first function.
. Pop two functions, concatenate them and push the result
+ Pop a function. If its a constant then increment it. Push it
- Pop a function. If its a constant then decrement it. Push it
< Get a character from STDIN and push it to the stack. Pushes -1 on EOF.
> Pop a function and print its ASCII character if its a constant
c Pop a function and print its value if its a constant
w Pop a function from the stack. Peek at the top of the stack. While it is
a non-zero constant, execute the function.
Komut istemine bir komut yazıldığında komut yürütülür. Tip #
(yinelenen komutu) istemi de. Görmelisin
> #
003: (-10)
002: (11)
001: (11)
>
(11) 'in kopyalandığına dikkat edin. Şimdi %
bilgi istemine yazın (drop komutu). Görmelisin
> %
002: (-10)
001: (11)
>
Yığına bir komut göndermek için parantez içine almanız yeterlidir. Tip (-)
istemi de. Bu işlem azaltma operatörünü yığına itecektir. Görmelisin
> (-)
003: (-10)
002: (11)
001: (-)
>
Bileşik fonksiyonlar
Bileşik bir fonksiyon oluşturmak için birden fazla atomik fonksiyonu parantez içine alabilirsiniz. Komut istemine bir bileşik işlevi girdiğinizde, işlev yığına itilir. Tip ($+$)
istemi de. Görmelisin
> ($+$)
004: (-10)
003: (11)
002: (-)
001: ($ + $)
>
Teknik olarak, yığındaki her şey bileşik bir işlevdir. Bununla birlikte, yığındaki bileşik fonksiyonların bazıları tek bir atomik fonksiyondan oluşur (bu durumda, kolaylık sağlamak için bunları atomik fonksiyonlar olarak kabul edeceğiz). Yığındaki bileşik işlevleri değiştirirken, .
komut (birleştirme) genellikle yararlıdır. Tip .
şimdi. Görmelisin
> .
003: (-10)
002: (11)
001: (- $ + $)
>
Yığındaki birinci ve ikinci işlevlerin birleştirildiğine ve yığındaki ikinci işlevin sonuç listesinde ilk geldiğine dikkat edin. Yığında bulunan bir işlevi yürütmek için (ister atomik ister bileşik olsun), w
komutu (while) vermeliyiz . w
Komut yığında ilk işlev pop ve çok uzun yığında ikinci fonksiyon, bir sıfır olmayan sabit olduğu gibi tekrar tekrar çalıştırır. Yazarsak ne olacağını tahmin etmeye çalışın w
. Şimdi yazın w
. Görmelisin
> w
002: (1)
001: (0)
>
Beklediğin bu mu? Yığın üstünde oturan iki sayı eklendi ve toplamları kaldı. Hadi tekrar dene. Önce sıfırı düşüreceğiz ve 10 yazarak yazacağız %10
. Görmelisin
> %10
002: (1)
001: (10)
>
Şimdi tüm işlevi bir çekimde yazacağız, ancak %
sıfırdan kurtulmak için sonuna bir ekstra ekleyeceğiz . Tip (-$+$)w%
istemi de. Görmelisin
> (-$+$)w%
001: (11)
>
(Bu algoritmanın yalnızca yığındaki ilk sabit pozitifse işe yaradığını unutmayın).
Teller
Dizeler de mevcuttur. Çoğunlukla sözdizimsel şekerdir, ancak oldukça yararlı olabilirler. Yorumlayıcı bir dizeyle karşılaştığında, her karakteri sondan ilkeye yığına iter. Tip %
Önceki örnekten 11 düşmesi. Şimdi 0 10 "Hi!"
bilgi istemini yazın. 0
Bir NULL Sonlandırıcı ekler ve 10
yeni bir satır karakteri ekler. Görmelisin
> 0 10 "Hi!"
005: (0)
004: (10)
003: (33)
002: (105)
001: (72)
>
Tür (>)w
biz NULL Sonlandırıcı karşılaşana kadar yığını karakterleri yazdırmak için. Görmelisin
> (>)w
Hi!
001: (0)
>
Sonuçlar
Umarım bu, tercümanla başlamanız için yeterli olacaktır. Dil tasarımı nispeten basit olmalıdır. Bir şeyin son derece belirsiz olup olmadığını bana bildirin :) Birkaç şey kasıtlı olarak belirsiz bırakıldı: değerler imzalanmalı ve en az 16 bit olmalı, yığın tüm referans programlarını çalıştıracak kadar büyük olmalıdır. tam bir üflemeli dil belirtimi yayınlamak için büyük ölçüde büyük olacaktır (ve henüz bir tane yazmadım: P). Şüphe duyduğunuzda referans uygulamasını taklit edin.