Tafsirkan Kipple!

12

pengantar

Kipple adalah bahasa pemrograman esoterik berbasis stack yang ditemukan oleh Rune Berg pada Maret 2003.

Kipple memiliki 27 tumpukan, 4 operator, dan struktur kontrol.

Tumpukan

Tumpukan diberi nama a- zdan berisi bilangan bulat bertanda 32-bit. Ada juga tumpukan khusus @,, untuk membuat angka keluaran lebih nyaman. Ketika suatu angka didorong ke atas @, nilai ASCII dari digit angka itu malah didorong sebagai gantinya. (Misalnya, jika Anda menekan 12 ke @, itu akan mendorong 49 dan kemudian 50 ke @.)

Input didorong ke tumpukan input isebelum program dijalankan. Juru bahasa akan meminta nilai untuk disimpan isebelum eksekusi. Setelah eksekusi selesai, semua yang ada di tumpukan ooutput akan ditampilkan sebagai karakter ASCII. Karena ini adalah satu-satunya mekanisme IO Kipple, berinteraksi dengan program Kipple tidak mungkin.

Operator

Operan adalah pengidentifikasi tumpukan atau bilangan bulat 32 bit yang ditandatangani.

Dorong: >atau<

Sintaks: Operand>StackIndentifieratauStackIndentifier<Operand

Operator Push mengambil operan ke kiri dan mendorongnya ke tumpukan yang ditentukan. Misalnya, 12>aakan mendorong nilai 12 ke tumpukan a. a>bakan memunculkan nilai teratas dari tumpukan adan mendorongnya ke tumpukan b. Memunculkan tumpukan kosong selalu mengembalikan 0. a<bsama dengan b>a. a<b>cmuncul nilai paling atas dari bdan mendorong keduanya cdan a.

Menambahkan: +

Sintaksis: StackIndentifier+Operand

Add operator mendorong jumlah item paling atas pada stack dan operan ke stack. Jika operan adalah tumpukan, maka nilainya muncul dari itu. Misalnya, jika nilai teratas tumpukan aadalah 1, maka a+2akan mendorong 3 ke atasnya. Jika akosong, maka a+2akan mendorong 2 ke atasnya. Jika nilai stack paling atas adan b1 dan 2, maka a+bakan muncul nilai 2 dari stack bdan mendorong 3 ke stack a.

Mengurangi: -

Sintaksis: StackIndentifier-Operand

Operator Kurangi bekerja persis seperti operator Tambah, kecuali bahwa itu mengurangi bukan menambah.

Bersih: ?

Sintaksis: StackIndentifier?

Operator Bersihkan mengosongkan tumpukan jika item paling atas adalah 0.

Penafsir akan mengabaikan segala sesuatu yang tidak di samping operator, sehingga program berikut akan bekerja: a+2 this will be ignored c<i. Namun, cara yang tepat untuk menambahkan komentar adalah dengan menggunakan #karakter. Apa pun antara a #dan karakter end-of-line dihapus sebelum eksekusi. Karakter ASCII # 10 didefinisikan sebagai end-of-line di Kipple.

Operan dapat dibagi oleh dua operator, mis. a>b c>b c?Dapat ditulis sebagai a>b<c?.

Program 1>a<2 a+aakan menghasilkan yang aberisi nilai-nilai [1 4](dari bawah ke atas) dan tidak [1 3]. Begitu juga untuk -operator.

Struktur Kontrol

Hanya ada satu struktur kontrol di Kipple: loop.

Sintaksis: (StackIndentifier code )

Selama tumpukan yang ditentukan tidak kosong, kode di dalam tanda kurung yang cocok akan diulang. Loop dapat berisi loop lain. Misalnya, (a a>b)akan memindahkan semua nilai tumpukan ake tumpukan b, meskipun urutannya akan terbalik . Cara yang identik secara fungsional, tetapi lebih elegan untuk melakukan ini adalah (a>b).

Contohnya

100>@ (@>o)

Ini akan menampilkan 100

33>o 100>o 108>o 114>o 111>o 87>o 32>o 111>o 108>o 108>o 101>o 72>o

Ini akan dicetak "Hello World!". Ketika otumpukan sedang di-output, ia mulai memunculkan karakter dari atas tumpukan ke bawah.

#prime.k by Jannis Harder
u<200
#change 200


k<2>m
u-2
(u-1 u>t u>z u<t
  (k>e e+0 e>r)
  (e>k)
  m+1
  m>t
  m>z
  m<t
  t<0>z? t?
  1>g
  (r>b
    m+0 m>a
    b+0 b>w
    (a-1 
      b+0 b>j
      j?
      1>s
      (j<0>s j?)
      s?
      (s<0 w+0 w>b s?)
      a>t
      a>z
      t>a
      b-1
      b>t
      b>z
      t>b
      z<0>t? z?
    a?)
    b?
    1>p
    (b<0 b? 0>p)
    p?
    (p 0>r? 0>p? 0>g)
  )
  g?
  (g m+0 m>k 0>g?)
u?)
(k>@
  10>o
  (@>o)
)

Ini adalah generator bilangan prima, tapi saya tidak yakin cara kerjanya.

Aturan

  • Anda harus menulis program / fungsi yang menafsirkan Kipple. Program / fungsi ini dapat memperoleh program Kipple melalui file sumber, atau mendapatkannya melalui STDIN langsung dari pengguna. Jika STDIN tidak tersedia, itu harus mendapatkannya dari input keyboard, dan terus mendapatkan input sampai karakter tertentu yang tidak patut dimasukkan. Misalnya, jika juru bahasa Anda ditulis dalam kode mesin x86, itu akan mendapatkan karakter program Kipple berdasarkan karakter dari keyboard, dan terus melakukannya sampai esc(atau tombol lain apa pun yang tidak memancarkan karakter yang dapat dicetak) ditekan.

  • Jika ada kesalahan, misalnya kesalahan sintaksis atau stack overflow, ia harus mengakuinya dengan cara tertentu, misalnya dengan mengembalikan 10 sebagai ganti 0 atau pesan kesalahan yang dihasilkan oleh penerjemah / kompiler, TETAPI TIDAK MENCETAK PESAN KESALAHAN .

  • Aturan reguler lainnya untuk golf kode berlaku untuk tantangan ini.

  • Kode Anda akan diuji dengan beberapa contoh di arsip sampel Kipple

Ini adalah . Kode terpendek dalam byte akan menang. Semoga berhasil!


Perhatikan bahwa ada operator opsional di Kipple,, "tetapi ini bukan bagian dari spesifikasi dan hanya fitur tambahan dalam juru bahasa resmi. Saya belum menyebutkannya di sini sehingga tidak perlu didukung dalam kiriman Anda.

Jika Anda ragu tentang bagian spesifikasi apa pun, Anda dapat memeriksanya dengan juru bahasa resmi yang ditulis dalam bahasa Jawa . Ini akan mengunduh file zip yang berisi program yang dikompilasi dan kode sumber. Ini dilisensikan di bawah GPL.


sumber
1
Apakah kita harus menggunakan integer bertanda 32-bit atau dapatkah kita menggunakan tipe integer alami implementasi host? (Kasing yang paling penting mungkin adalah bilangan bulat 32-bit yang tidak ditandatangani, bilangan bulat 8-bit yang ditandatangani atau tidak dan bilangan bulat presisi arbitrer.)
Martin Ender
baik, itulah yang saya temukan di wiki esotric. ya, karena penerjemah Anda mungkin tidak kompatibel dengan program kipple lain yang mekanismenya didasarkan pada fitur ini
Bisakah Anda lebih spesifik tentang perilaku dalam hal kesalahan? Jadi kami dapat mengembalikan jawaban yang salah atau memancarkan kesalahan, tetapi kami tidak dapat mencetak kesalahan?
Alex A.
@Alex A. Ya, karena itu dapat dianggap sebagai output program, dan Anda dapat membuat program kipple yang dapat memiliki output yang sama dengan pesan kesalahan. Juga lebih murah (menggunakan lebih sedikit karakter) untuk tidak memiliki fungsi / pernyataan yang mencetak pesan kesalahan.
3
Spasi apa yang dapat terjadi dalam program sumber? Bagaimana saya bisa meminta input ijika saya mengambil program sumber dari stdin?
orlp

Jawaban:

6

C, 709 702 byte

Skor byte dengan baris baru (yang dapat dihapus) dihapus, tetapi untuk kemudahan membaca saya mempostingnya di sini dengan baris baru:

#define R return
#define C ;break;case
c[999]={};*P=c;*S[28];M[99999]={};t;*T;
u(s,v){S[s]+=28;*S[s]=v;
if(s>26){for(t=v/10;t;t/=10)S[s]+=28;T=S[s];do{*T=48+v%10;T-=28;}while(v/=10);}}
o(s){t=S[s]-M>27;S[s]-=28*t;R S[s][28]*t;}
I(s){R s<65?27:s-97;}
O(int*p){if(!isdigit(*p))R o(I(*p));
for(;isdigit(p[-1]);--p);for(t=0;isdigit(*p);t*=10,t+=*p++-48);R t;}

main(i,a){for(i=0;i<28;++i)S[i]=M+i;
for(;~(*++P=getchar()););P=c+1;
for(;;){i=I(P[-1]);switch(*P++){
case 35:for(;*P++!=10;)
C'<':u(i,O(P))
C'>':u(I(*P),O(P-2))
C'+':u(i,*S[i]+O(P))
C'-':u(i,*S[i]-O(P))
C'?':if(!*S[i])S[i]=M+i
C'(':for(i=1,T=P;i;++T)i+=(*T==40)-(*T==41);if(S[I(*P)]-M<28)P=T;else u(26,P-c)
C')':P=c+o(26)-1
C-1:for(;i=o(14);)putchar(i); R 0;}}}

Kompilasi dengan gcc -w golf.c( -wmembungkam peringatan untuk kewarasan Anda).

Mendukung semuanya kecuali iinput, karena penanya belum menanggapi pertanyaan saya tentang bagaimana melakukannya jika Anda mengambil kode dari stdin. Itu tidak melaporkan kesalahan sintaksis.

orlp
sumber
Saya telah menjawab pertanyaan Anda tentang "i" yang ditumpuk di komentar posting utama.
btw bagaimana cara membaca program kipple? melalui argumen perintah? bagaimana saya harus menggunakannya?
@ GLASSIC Ia mengharapkan program di stdin.
orlp
Sampai kapan ? Bagaimana cara memulai eksisi?
@ GLASSIC Baru saja lulus program di stdin. Misalnya ./a.out < prime.k.
orlp
3

Ruby, 718 byte (saat ini tidak bersaing)

aku sangat lelah

File dimuat sebagai argumen baris perintah, dan input dikirim melalui STDIN. Atau, pipa file ke STDIN jika Anda tidak perlu input dalam iregister Anda .

Karena beberapa kebingungan mengenai spesifikasi, versi saat ini tidak menangani a<b>cdengan benar, dan karenanya tidak bersaing hingga diperbaiki.

a<b>csudah diperbaiki sekarang. Namun, itu masih mengembalikan hasil yang salah ketika menjalankan fungsi bilangan prima, sehingga masih tetap sebagai jawaban yang tidak bersaing.

(f=$<.read.gsub(/#.*?\n|\s[^+-<>#()?]*\s/m,' ').tr ?@,?`
t=Array.new(27){[]}
t[9]=STDIN.read.bytes
k=s=2**32-1
r=->c{c=c[0];c[0]==?(?(s[c[1..-2]]while[]!=t[c[1].ord-96]):(c=c.sub(/^(.)<(\D)>(.)/){$1+"<#{t[$2.ord-96].pop||0}>"+$3}.sub(/(\d+|.)(\W)(\d+|.)?/){_,x,y,z=*$~
a=x.ord-96
b=(z||?|).ord-96
q=->i,j=z{j[/\d/]?j.to_i: (t[i]||[]).pop||0}
l=t[a]
y<?-?(x==z ?l[-1]*=2:l<<(l.pop||0)+q[b]
l[-1]-=k while l[-1]>k/2):y<?.?(x==z ?l[-1]=0:l<<(l.pop||0)-q[b]
l[-1]+=k while l[-1]<-k/2-1):y<?>?t[a]+=a<1?q[b].to_s.bytes: [q[b]]:y<???
(t[b]+=b<1?q[a,x].to_s.bytes: [q[a,x]]): l[-1]==0?t[a]=[]:0
z||x}while c !~/^(\d+|.)$/)}
s=->c{(z=c.scan(/(\((\g<1>|\s)+\)|[^()\s]+)/m)).map &r}
s[f]
$><<t[15].reverse.map(&:chr)*'')rescue 0
Nilai Tinta
sumber
Tetap memberi +1. Apakah Anda mencoba program fibonacci?
edc65
@ edc65 Program urutan Fibbonacci mencetak hal yang salah juga: 0 1 1 2 4 8 16...Saya ingin tahu apakah ini kesalahan spesifikasi
Nilai Tinta
Tidak, program Fibonacci adalah omong kosong, misalnya garis a+0itu omong kosong
edc65
Saya kira masalah tentang bilangan prima adalah bahwa ia tidak menangani struktur kontrol bersarang, tetapi saya tidak tahu banyak tentang ruby, saya ragu dugaan saya benar.
Program ini harus menangani set parens bersarang dengan benar karena kecocokan regex rekursif /(\((\g<1>|\s)+\)|[^()\s]+)/myang digunakannya untuk membagi pada token dan grup token. ( Uji pada regex101 ). Mungkin kesalahan di sisa parsing saya, tapi saya tidak tahu di mana.
Nilai Tinta