Interpreta Kipple!


12

introduzione

Kipple è un linguaggio di programmazione esoterico basato su stack inventato da Rune Berg nel marzo 2003.

Kipple ha 27 stack, 4 operatori e una struttura di controllo.

Stacks

Le pile sono chiamati a- ze contengono interi con segno a 32 bit. C'è anche uno stack speciale @, per rendere più conveniente la produzione di numeri. Quando viene inserito un numero, vengono invece spinti @i valori ASCII delle cifre di quel numero. (Ad esempio, se si preme 12 su @, spingerà invece 49 e poi 50 su @.)

L'input viene inserito nello stack di input iprima dell'esecuzione del programma. L'interprete chiederà di memorizzare i valori iprima dell'esecuzione. Al termine dell'esecuzione, qualsiasi cosa nello stack di output oviene visualizzata in output come carattere ASCII. Poiché questo è l'unico meccanismo IO di Kipple, è impossibile interagire con un programma Kipple.

operatori

Un operando è un identificatore di stack o un numero intero a 32 bit con segno.

Push: >o<

Sintassi: Operand>StackIndentifieroStackIndentifier<Operand

L'operatore Push porta l'operando a sinistra e lo inserisce nello stack specificato. Ad esempio, 12>aspingerà il valore 12 nello stack a. a>bfarà apparire il valore più alto dallo stack ae lo spingerà nello stack b. Popping uno stack vuoto restituisce sempre 0. a<bequivale a b>a. a<b>cmostra il massimo valore da be spinge verso entrambi ce a.

Inserisci: +

Sintassi: StackIndentifier+Operand

L'operatore Aggiungi inserisce la somma dell'elemento più in alto nella pila e l'operando nella pila. Se l'operando è uno stack, il valore viene estratto da esso. Ad esempio, se il valore più alto dello stack aè 1, quindi a+2spingerà 3 su di esso. Se aè vuoto, a+2spingerà 2 su di esso. Se i valori più alti dello stack ae bsono 1 e 2, quindi a+bfarà apparire il valore 2 dallo stack be spingerà 3 nello stack a.

Sottrarre: -

Sintassi: StackIndentifier-Operand

L'operatore Sottrai funziona esattamente come l'operatore Aggiungi, tranne per il fatto che sottrae invece di aggiungere.

Chiaro: ?

Sintassi: StackIndentifier?

L'operatore Clear svuota lo stack se il suo oggetto più in alto è 0.

L'interprete ignorerà tutto ciò che non si trova accanto a un operatore, in modo che il seguente programma avrebbe funzionato: a+2 this will be ignored c<i. Tuttavia, il modo corretto di aggiungere commenti è usando il #personaggio. Qualsiasi cosa tra #un carattere di fine riga e viene rimosso prima dell'esecuzione. Il carattere ASCII n. 10 è definito come fine linea in Kipple.

Gli operandi possono essere condivisi da due operatori, ad esempio a>b c>b c?possono essere scritti come a>b<c?.

Il programma 1>a<2 a+acomporterà il acontenimento dei valori [1 4](dal basso verso l'alto) e non [1 3]. Allo stesso modo per l' -operatore.

La struttura di controllo

C'è solo una struttura di controllo in Kipple: il loop.

Sintassi: (StackIndentifier code )

Finché lo stack specificato non è vuoto, il codice tra parentesi corrispondenti verrà ripetuto. I loop possono contenere altri loop. Ad esempio, (a a>b)tutti i valori dello stack verranno spostati nello astack b, anche se l'ordine verrà invertito . Un modo funzionalmente identico, ma più elegante per farlo è (a>b).

Esempi

100>@ (@>o)

Questo produrrà 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

Questo stamperà "Hello World!". Quando lo ostack viene emesso, inizia a far apparire i caratteri dall'alto verso il basso.

#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)
)

Questo è un generatore di numeri primi, ma non sono sicuro di come funzioni.

Regole

  • Devi scrivere un programma / una funzione che interpreta Kipple. Questo programma / funzione può ottenere un programma Kipple tramite un file sorgente o ottenerlo tramite STDIN direttamente dall'utente. Se STDIN non è disponibile, deve ottenerlo dall'input da tastiera e continuare a ricevere l'input fino a quando non viene inserito uno specifico carattere non stampabile. Ad esempio, se l'interprete è scritto in codice macchina x86, otterrebbe il programma Kipple carattere per carattere dalla tastiera e continuerebbe a farlo fino a quando esc(o qualsiasi altro tasto che non emette un carattere stampabile) viene premuto.

  • Se si verifica un errore, ad esempio un errore di sintassi o un overflow dello stack, è necessario riconoscerlo in qualche modo, ad esempio restituendo 10 anziché 0 o messaggi di errore prodotti dall'interprete / compilatore, MA NON STAMPARE MESSAGGI DI ERRORE .

  • Per questa sfida si applicano altre regole regolari per il golf del codice.

  • Il tuo codice verrà testato con alcuni degli esempi nell'archivio degli esempi di Kipple

Questo è un . Vincerà il codice più breve in byte. In bocca al lupo!


Nota che esiste un operatore opzionale in Kipple, "ma non fa parte delle specifiche e è solo una funzione aggiuntiva nell'interprete ufficiale. Non l'ho menzionato qui, quindi non deve essere supportato nella tua richiesta.

In caso di dubbi su qualsiasi parte della specifica, è possibile esaminarla con un interprete ufficiale scritto in Java . Questo scaricherà un file zip contenente il programma compilato e il codice sorgente. È concesso in licenza ai sensi della GPL.


1
Dobbiamo dobbiamo utilizzare interi con segno a 32 bit o possiamo andare con tipo intero naturale della implementazione host? (I casi più importanti sono probabilmente numeri interi a 32 bit senza segno, numeri interi a 8 bit con segno o senza segno e numeri interi con precisione arbitraria.)
Martin Ender

bene, era quello che ho trovato sul wiki esoterico. sì, perché il tuo interprete potrebbe essere incompatibile con altri programmi kipple il cui meccanismo si basa su questa funzione

Puoi essere più specifico sul comportamento in caso di errori? Quindi possiamo restituire una risposta errata o emettere un errore, ma non possiamo stampare l'errore?
Alex A.

@Alex A. Sì, perché può essere considerato l'output del programma ed è possibile creare un programma kipple che può avere lo stesso output del messaggio di errore. Inoltre è "più economico" (usa meno caratteri) non avere una funzione / istruzione che stampa un messaggio di errore.

3
Quale spazio bianco può verificarsi in un programma sorgente? Come posso chiedere input ise prendo il programma sorgente da stdin?
orlp,

Risposte:


6

C, 709 702 byte

Il punteggio in byte viene rimosso con le nuove righe (che possono essere rimosse), ma per facilità di lettura lo inserisco qui con le nuove righe:

#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;}}}

Compila gcc -w golf.c( -wavvisi di silenzio per la tua sanità mentale).

Supporta tutto tranne l' iinput, poiché il richiedente non ha ancora risposto alla mia richiesta su come farlo se si prende il codice da stdin. Non segnala errori di sintassi.


ho risposto alla tua domanda sulla pila "i" nei commenti del post principale.

a proposito come legge i programmi kipple? tramite argomenti di comando? come dovrei usarlo?

@GLASSIC Si aspetta il programma su stdin.
orlp,

Fino a quando ? Come iniziare l'escissione?

@GLASSIC Basta passare il programma su stdin. Es ./a.out < prime.k.
orlp,

3

Ruby, 718 byte (attualmente non competitivo)

sono molto stanco

Il file viene caricato come argomento della riga di comando e l'input viene inviato tramite STDIN. In alternativa, reindirizza il file in STDIN se non hai bisogno di input nel tuo iregistro.

A causa di un po 'di confusione per quanto riguarda le specifiche, la versione corrente non viene gestita a<b>ccorrettamente e pertanto non è competitiva fino a quando non viene risolta.

a<b>cè stato risolto ora. Tuttavia, restituisce comunque un risultato errato quando si esegue la funzione primes, quindi rimane comunque una risposta non competitiva.

(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

+1 comunque. Hai provato il programma fibonacci?
edc65,

@ edc65 Il programma di sequenza Fibbonacci stampa anche la cosa sbagliata: 0 1 1 2 4 8 16...mi chiedo se si tratta di un errore di specifica
Value Ink

No, il programma Fibonacci è una schifezza, per esempio la linea a+0è senza senso
edc65

immagino che il problema dei numeri primi sia che non gestisce le strutture di controllo nidificate, ma non so molto sul rubino, dubito che la mia ipotesi sia corretta.

Questo programma dovrebbe gestire correttamente le serie nidificate di parentesi a causa della corrispondenza regex ricorsiva /(\((\g<1>|\s)+\)|[^()\s]+)/mche utilizza per dividere su token e gruppi di token. ( Provalo su regex101 ). Probabilmente è un errore nel resto dell'analisi, ma non so dove.
Value Ink,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.