Volatile interpretieren

11

Volatile interpretieren

Volatile ist ein stapelbasierter Esolang von A_ / a '_' / A, der nur 8 Anweisungen enthält und vollständig ist. Es ist jedoch auch nicht deterministisch ... was bedeutet, dass Programme nicht immer die gleiche Ausgabe liefern. Ihre Aufgabe ist es, diese Sprache zu interpretieren.

Sprachspezifikationen

Entnommen von der Esolangs-Seite:

~: Push a random integer in any range of integers. Minimum range of 0 through 32768

+: Pop 2 values and push the sum of the 2 values

-: Like +, but subtracts

*: Multiply

/: Divide. 0-division will result in an error.

:: Duplicate the top of the stack

.: Output the top of the stack without popping it


(...): Execute ... inside a while loop when the top of the stack is not 0

Alles andere wird ignoriert

Eingang

Beachten Sie, dass diese Programme möglicherweise zufällig fehlschlagen

~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.~:/:::::::::::::::::::::::::::::::::+++++++++++++++++++++++++++++++++.~:/::::::::::++++++++++.

~:-.~:/+.(~:/+.)

~:-:/

Ausgabe

73 102 109 109 112 45 33 120 112 115 109 101 34 11

0 1 2 3 4 5 6 7 8 9 ...

<Any Error Message>

Weitere Beispiele sowie eine Referenzimplementierung (verwenden Sie die zweite unter (Ein anderer) Python 3-Interpreter ) finden Sie unter https://esolangs.org/wiki/Volatile

Wertung

Dies ist Code-Golf, also gewinnt die kürzeste Antwort in Bytes

Bestenlisten

Hier ist ein Stack-Snippet, mit dem Sie sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache erstellen können.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift unter Verwendung der folgenden Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihrer Einreichung? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Wenn Sie dort mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder Sie die Strafen für Dolmetscherflaggen separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:

# Perl, 43 + 2 (-p flag) = 45 bytes

Sie können den Sprachnamen auch zu einem Link machen, der dann im Leaderboard-Snippet angezeigt wird:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

Lyxal
quelle
2
Soll die Division auf 0 runden?
Grimmy
Schiebt ~eine ganze Zahl oder eine beliebige Zahl?
mbomb007
1
Abhängig von der Implementierung ist dies möglicherweise nicht wirklich nicht deterministisch. Sicher, die Esolang-Seite behauptet, dass dies der Fall ist, aber das liegt nur an der aufgeführten Art zu pushen 1, die sich durch Null teilen könnte. ~muss in der Lage sein, Null zu drücken, sonst ist es deterministisch. Außerdem muss das RNG immer in der Lage sein, nach einer beliebigen Anzahl von Nullen in einer Reihe Null zurückzugeben.
mbomb007
2
Sollte nicht die zweite Eingang ~:-.~:/+.(~:/+.)von starten 0 1 2 ...statt 1 2 3 ...? Das ~:-.würde zu 0 führen, die es ausgibt. Diese Dolmetscher auf der Esolang-Seite scheinen dies zu bestätigen ( hier die zweite ).
Kevin Cruijssen
2
Vorschlag, Testfall hinzuzufügen:~:-.(~:/+.)
Nacht2

Antworten:

6

05AB1E , 35 Bytes

"~:/.()"”žGÝΩ DŠéõq}÷ = [D_# }”#‡.V

Probieren Sie es online aus!

Transpiliert flüchtigen Code in 05AB1E und wertet ihn dann aus. *, +Und -kann wie sie ist gelassen werden. :, .Und )haben einen direkten Ein-Byte - Äquivalent. Die anderen Befehle benötigen jeweils einige Bytes. Leider stürzt 05AB1E bei der Division durch 0 nicht ab, sodass dies stattdessen durch ein bedingtes "Beenden, wenn der Stapel oben ist == 0" implementiert wird.

Grimmy
quelle
1
Funktioniert das für die Schleife richtig? Wenn ich den zweiten Testfall eingebe, scheint er vor der Schleife ausgegeben 0und 1korrekt zu sein, aber dann beginnt er mit der Ausgabe des Volatile-Programms (der impliziten Eingabe) selbst. Ich mag diese D DoingõqWörterbuchzeichenfolge für die if-Anweisung, übrigens! :)
Kevin Cruijssen
1
@ KevinCruijssen Das Beispiel scheint anzunehmen, dass die Schleife eine ist while peek, aber im Referenzinterpreter ist es eine while pop. Das Beispiel kann durch Hinzufügen einiger :( TIO ) behoben werden . Alternativ kann mein Code while peekdurch Hinzufügen von a in a geändert werden D.
Grimmy
1
Beide Referenzdolmetscher aus dem Esolang geben jedoch weiterhin aus 0 1 2 3 .... Ich habe mir ihren Quellcode nicht angesehen, sondern nur beide ausprobiert.
Kevin Cruijssen
1
@ KevinCruijssen Oh, die Funktion heißt Pop, ist aber eigentlich ein Blick. Maximal verwirrend. Ich habe das Din meinen Code eingefügt .
Grimmy
Lol .. Verwirrende eingebaute Namen erinnern mich an Javas replacevs replaceAll(die beide alle Vorkommen ersetzen, aber die replaceAllregulären Ausdrücke verwenden und die andere nicht). xD
Kevin Cruijssen
4

Julia 1.0 , 334 Bytes

a\b=push!(a,b)
a=pop!(a)
v(q,s=[],l=0)=(i=1;
for c in q
!r=c==r
i+=1
!')' ? (l<1 && break;l-=1) :
!'(' ? (while s[end]!=0 v(q[i:end],s) end;l+=1) :
l>0 ? continue :
!'~' ? s\rand(Int) : 
!'+' ? s\(s+√s) :
!'-' ? s\(s-√s) :
!'*' ? s\(s*√s) :
!'/' ? s\(s÷√s) :
!':' ? s\s[end] :
!'.' ? print(s[end]," ") : 0
end)

Mein erster "Dolmetscher" jeglicher Art war einfacher als ich erwartet hatte. Ich habe ein bisschen Golf gespielt, aber es gibt wahrscheinlich Platz für mehr. Ich habe es ein Leerzeichen nach der Ausgabe für drucken lassen. zu Beispielausgabe machen. Die ungolfed Version befindet sich in der Kopfzeile des TIO-Links. Anwendungsbeispiel v("~:-:/").

+41 Bytes zur Behebung des Fehlers, auf den Night2 durch Hinzufügen eines Schleifenzählers hingewiesen hat. Jetzt verstehe ich, warum Transpiling eine gute Option ist. Ein guter Testfall ist ~:-.(~:/+.)(~:/+.())~:-.mit erwarteter Leistung0 0

Probieren Sie es online aus!

gggg
quelle
3

Runenverzauberungen , 266 264 Bytes

DS͗{r;'ui[0[0y̤<<<<<?+f2,;$"!0/"?*7≠0:S͗\
RS͗}:'~=?!\:':=?!\:'+=?!\:'-=?!\:'/=?!/:'.=?!\:'*=?!\:';=?!;:')≠3*?04B͍:'(=?!S͗
U/lA`R耀`S͗/?7  :S͗/?+f1+S͗/?3  -S͗/?3     $ '$:S͗/?7  *S͗/
U\m(d*?"SO!"$;
{:'(=?!\:')=?!\R
~/?)0l{͗/?8 {͗l}͗/U
 \}͗21B͍

Probieren Sie es online aus!

Aufgrund der in Runic integrierten Einschränkungen können nur Programmlängen (und Stapelgrößen) von ~ 50 1 unterstützt werden . Zu große Programme schlagen einfach fehl. Wenn der Stapel zu groß wird, tritt ein Fehler auf SO!(war nicht erforderlich, war aber besser als eine stille Beendigung; kostet 24 Byte). Wenn das Programm versucht, durch 0 zu teilen, wird es gedruckt /0!.

Fehler werden an das Ende der Standardausgabe angehängt, da Runic nicht in STDERR schreiben kann.

Diese Version unterstützt beliebig lange Programme, ist jedoch immer noch auf einen Stapel von ~ 90 beschränkt (und führt daher zu Fehlern beim 2. Ergebnis des ersten Testprogramms) und wurde nicht sehr gut gespielt (die Erhöhung der Befehlslänge zwischen S͗}:und S͗}͍:0%:erforderte einige zusätzlicher Abstand, um Abschnitte auszurichten, aber dieser zusätzliche Platz ermöglichte auch mehr <für eine größere maximale Stapelgröße).

Alternativ vermeidet dieses Programm das ~Generieren einer Null und das Programm wird nach 1 Million Ausführungsschritten beendet (ein Schutz gegen Endlosschleifen, die in den Runeninterpreter eingebaut sind). Enthält auch einige Bytes, um überschüssigen NOP-Speicherplatz zu überspringen und etwas länger zu laufen.

  1. Stack Oversize Fizzling tritt bei (IP Mana + 10) auf und der Check, den ich für Volatile's Stack eingegeben habe, ist sizeof(stack) < manaund es gibt 5 IPs, die ihr Mana zusammenführen und kombinieren (50 Initialen). Das Erhöhen dieses Wertes auf das wahre Limit (+10) würde weitere 2 Bytes kosten, und ich habe die Logik nicht genau, sondern golfig gelassen.

Erläuterung

Flüchtiger Fluss

  1. Das Programm beginnt im oberen mittleren blauen Bereich entlang der <<<<<und die fünf IPs werden am zusammengeführty
  2. IP bewegt sich nach links, richtet die Stapel und Leseeingaben ein und wechselt zum Cyan-Bereich
  3. IP bewegt sich in dieser Zeile nach rechts und überprüft das oberste Zeichen auf dem Stapel, um welchen Befehl es sich handelt. Diese Linie verläuft weiter rechts als sichtbar. Wenn die richtige Anweisung gefunden wurde, wird der Code in der Zeile links unten ausgeführt (andere Abschnitte werden übersprungen, um über das Blau zum Cyan zurückzukehren).
  4. Der Magenta-Abschnitt wird während ~oder bei einem Befehl :zum Fehler beim Stapelüberlauf ausgeführt. Der gelbe Abschnitt wird übersprungen, wenn der Stapel nicht überfüllt ist, und kehrt über den Umlauf in das Dunkelblau zurück.
  5. Weit rechts, wenn das )gefunden wird, verzweigt sich das Programm in den roten Bereich und bewegt sich nach rechts.
  6. In diesem Abschnitt wird der Befehlsstapel nach rechts gedreht, bis a (gefunden wird (weiter grün).
  7. Für jedes weitere )gefunden wird (weiter orange), der Stapeltiefenstapel wird gestoßen, und wenn a (gefunden wird, wird der Stapeltiefenstapel einmal geplatzt (dunkelgrüner und orangefarbener Wiedereintritt fortfahren).
  8. Wenn der Tiefenstapel leer ist, folgen Sie weiter grün bis Bund kehren Sie zu Cyan zur Hauptparsing-Schleife zurück. Andernfalls wickeln Sie über Orange-> Gelb-> Rot (erneutes Aufrufen der Loop-Reset-Schleife).
  9. Das Purpur oben rechts behandelt die Division. Wenn der zu teilende Wert 0 ist, behandelt der braune Bereich den Fehler und die Beendigung. Betritt die Hauptparsing-Schleife erneut, indem der Cyan-Abschnitt übersprungen wird.
Draco18s vertraut SE nicht mehr
quelle
2

PHP , 196 Bytes

eval(strtr($argn,[':'=>($v='$a[]=').$e='end($a);','~'=>$v.'rand();','+'=>($q=$v.$p='array_pop($a)')."+$p;",'-'=>"$q-$p;",'*'=>"$q*$p;",'/'=>"$q/$p;",'.'=>"echo' ',$e",'('=>"for(;$e){",')'=>'}']));

Eingabe 1: Probieren Sie es online aus!

Eingabe 2 (0, 1, 2, ...): Probieren Sie es online aus!

Eingabe 3 (Fehler durch Division durch Null): Probieren Sie es online aus!

Übersetzt einfach den Code in PHP und wertet ihn aus!

Nacht2
quelle
2

JavaScript (V8) ,  178 172  171 Bytes

Transpiles zu JS. Kann entweder werfen Z is not definedoder x is not definedwenn der Code versucht, etwas Schlechtes zu tun.

s=>eval(s.replace(/./g,c=>`S.push(${c>'}'?'x=Math.random()*1e5|0':c>'9'?'x':c=='.'?');print(x':c<')'?');while(x){(0':c<'*'?')}(0':`1/(x${c}=S.pop(S.pop()))?x:Z`});`,S=[]))

Probieren Sie das 1. Programm online aus!

Probieren Sie das 2. Programm online aus!

Probieren Sie das 3. Programm online aus!

Wie?

Jede Anweisung wird transpiliert S.push(, gefolgt von einem bestimmten Muster, gefolgt von );.

Wir müssen die Division durch Null explizit testen, weil JS sich nicht im geringsten um eine so harmlose Operation kümmert. :-p

verkohlen. | JS-Code
------- + --------------------------------------
   ~ | S. push ( x = Math.random () * 1e5 | 0 );
   + | S. push ( 1 / (x + = S. pop (S. pop ())) & Dgr; x: Z );
   - | S. push ( 1 / (x- = S. pop (S. pop ())) & Dgr; x: Z );
   * | S. push ( 1 / (x * = S. pop (S. pop ())) & Dgr; x: Z );
   / | S. push ( 1 / (x / = S. pop (S. pop ())) & Dgr; x: Z );
   : | S.push ( x );
   . | S. push ( ); print (x );
   (| S.push ( ); while (x) {(0 );
   ) | S. push ( )} (0 );
Arnauld
quelle
2

Java 8, 420 418 402 373 359 357 341 Bytes

import java.util.*;s->f(s,new Stack());void f(String s,Stack<Integer>S){for(int i=0,c,t,u;i++<s.length();){if((c=s.charAt(i-1))<42&&S.peek()!=0)f(s.substring(40/c*i),S);if(c==46)System.out.println(S.peek());if(c>57)S.add(c>99?new Random().nextInt():S.peek());if(c<44|c==45|c==47){t=S.pop();u=S.pop();S.add(c<43?u*t:c<45?u+t:c<46?u-t:u/t);}}}

-2 Bytes dank @Grimy .
-16 Bytes dank @ceilingcat .

Probieren Sie es online aus.

Erläuterung:

import java.util.*;       // Required import for 2x Stack and Random

s->                       // Method with String parameter and no return-type
  f(s,new Stack())        //  Call the recursive function, with a new Stack

// Separated recursive method with String and Stack parameters
void f(String s,Stack<Integer>S){
  int i=0,                //  Index integer
      c,                  //  Temp integer used for the current character
      t,u;                //  Temp integers used for the peeked/popped top of the stack
  for(;i++<s.length();){  //  Loop `i` in the range [0, String-length):
    if((c=s.charAt(i-1))  //   Set `c` to the current character
        <42               //   If the character is either '(' or ')',
        &&S.peek()!=0)    //   and the top of the stack is not 0:
         f(s.substring(   //    Take the substring, either removing everything before and
            40/c*i),      //    including the "(", or keeping the string as is for ")"
           S);            //    And do a recursive call with this String
    if(c==46)             //    If the character is '.'
      System.out.println( //     Print with trailing newline:
       S.peek());         //      The peeked top of the stack
    if(c>57)              //    If the character is ':' or '~':
      S.add(c>99?         //     If the character is '~':
        new Random().nextInt()
                          //      Add a random [0,2147483647) integer to the stack
       :                  //     Else (the character is ':')
        S.peek());        //      Add the peeked top to the stack
    if(c<44|c==45|c==47)  //    If the character is '*', '+', '-', or '/':
      t=S.pop();u=S.pop();//    Pop and set the top two values to `t` and `u`
      S.add(c<43?         //     If the character is '*':
        u*t               //      Add the product of the two values to the stack
       :c<44?             //     Else-if the character is '+':
        u+t               //      Add the sum of the two values to the stack
       :c<46?             //     Else-if the character is '-':
        u-t               //      Subtract the top two values, and add it to the stack
       :                  //     Else (the character is '/'):
        u/t;}}}           //      Divide the top two values, and add it to the stack
Kevin Cruijssen
quelle
1
new Random().nextInt()ist 2 kürzer als (int)(Math.random()*1e5).
Grimmy
@Grimy Ah, ich habe vergessen, dass ich diesen java.util.*Import für die hatte Stack. Vielen Dank! :)
Kevin Cruijssen
@ceilingcat Danke für -16!
Kevin Cruijssen
Dies geht wahrscheinlich gegen eine oder mehr Regeln des Anstandes , aber wenn Sie ersetzen new Random().nextInt()mit 5allen Testfällen noch passieren.
Deckenkatze
@ceilingcat Ja, aber 5nicht gerade zufällig ;) Relevante xkcd
Kevin Cruijssen
2

C (gcc) für Linux x86_64, 675 643 621 613 597 432 404 399 Byte

printf();*z;*mmap();(*p)();*j(char*a){char*t=a,*n,c;for(p=0;read(0,&c,!p);t=!~c?n=j(t+9),z=mempcpy(t,L"\xf00f883Ƅ",5),*z=n-t-9,n:!c?p=*t++=233,z=t,*z=a-13-t,z+1:stpcpy(t,c-85?c-2?c-4?c-1?c-6?c-17?"PAPTYh%ld T_P^1\xc0QH\x83\xcc\bQA\xff\xd0\\AXX":"P":L"\xfef7995e":"[\xf7\xeb":"[)\xd8":"[\1\xd8":L"\xf0c70f50"))c-=41;return t;}main(){p=mmap(0,1<<20,6,34,0,0);p(strcpy(j(p),"j<X\xf\5"),0,0,0,printf);}

Probieren Sie es online aus!

Dies ist eine JIT, die flüchtige Anweisungen direkt in die Maschinensprache x86_64 übersetzt und den Code ausführt. Wenn Ihr Rechner die nicht hat rdrandAnweisung, können Sie ersetzen L"\xf0c70f50"mit "Pj*X"einem „ weniger einheitlich PRNG “. Um den Port auf etwas anderes als Linux, ersetzen Sie die syscalls in den printf()und exit()Kleckse und Einstellen von Parametern zu mmap().

BEARBEITEN: Diese Version ruft auf, printf()anstatt eine Teilmenge von Grund auf neu zu implementieren.

EDIT2: Unterstützte Ganzzahlen sind jetzt 32 Bit statt 64.

Etwas weniger Golf ...

printf();*z;*mmap();(*p)();
// recursive function translates Volatile commands to x86_64 instructions
*j(char*a){
  char*t=a,*n,c;
  for(p=0;read(0,&c,!p);)
    c-=41,
    t=c=='('+41?
      // cmp eax,0
      // je n-t-9
      n=j(t+9),
      z=mempcpy(t,"\x83\xf8\x00\x0f\x84",5),
      *z=n-t-9,
      n
    :
      c==')'+41?
        // jmp a-13-t
        p=*t++=233,
        z=t,
        *z=a-13-t,
        z+1
      :
        stpcpy(t,c-'~'+41?
                   c-'+'+41?
                     c-'-'+41?
                       c-'*'+41?
                         c-'/'+41?
                           c-':'+41?
                             // ; This calls printf("%ld ",%rax)
                             // push rax
                             // push r8
                             // push rsp
                             // pop  rcx
                             // push 0x20646c25
                             // push rsp
                             // pop  rdi
                             // push rax
                             // pop  rsi
                             // xor  eax, eax
                             // push rcx
                             // or   rsp, 8
                             // push rcx
                             // call r8
                             // pop  rsp
                             // pop  r8
                             // pop  rax
                             "\x50\x41\x50\x54\x59\x68\x25\x6c\x64\x20\x54\x5f\x50\x5e\x31\xc0\x51\x48\x83\xcc\x08\x51\x41\xff\xd0\x5c\x41\x58\x58"
                           :
                             // push rax
                             "\x50"
                         :
                           // pop rsi
                           // cdq  
                           // idiv esi
                           "\x5e\x99\xf7\xfe"
                       :
                         // pop rbx
                         // imul ebx
                         "\x5b\xf7\xeb"
                     :
                       // pop rbx
                       // sub eax, ebx
                       "\x5b\x29\xd8"
                   :
                     // pop rbx
                     // add eax, ebx
                     "\x5b\x01\xd8"
                 :
                   // push rax
                   // rdrand eax
                   "\x50\x0f\xc7\xf0");
  return t;
}
main(){
  p=mmap(0,1<<20,6,34,0,0);
  p(strcpy(j(p),"\x6a\x3c\x58\x0f\x05"),0,0,0,printf);
}
Deckenkatze
quelle
1

Kotlin , 412 Bytes

Leider habe ich gegen Java verloren, aber ich wollte nicht import java.util.Stack(und ich bin mir nicht sicher, ob es die Lücke trotzdem schließen würde.)

{p->var i=0
var s=List(0){0}
var c=List(0){0}
while(i<p.length){when(val o=p[i]){'~'->s+=(0..32768).random()
in "+-*/"->{val(a,b)=s.takeLast(2)
s=s.dropLast(2)+when(o){'+'->a+b
'-'->a-b
'*'->a*b
'/'->a/b
else->0}}
':'->s+=s.last()
'.'->println(s.last())
'('->{if(s.last()!=0)c+=i else{var z=0
do{if(p[i]=='(')z++else if(p[i]==')')z--
i++}while(z>0)
i--}}
')'->if(s.last()!=0)i=c.last()else c=c.dropLast(1)}
i++}}

Ungolfed

{ p ->                  // open lambda: p is the code string
    var i = 0           // program counter
    var s = List(0){0}  // data stack
    var c = List(0){0}  // jump stack

    // main loop
    while(i<p.length) {
        // match on the current character
        when(val o = p[i]) {
            // add random number to end of stack
            '~' -> s += (0..32768).random()
            // if a math op...
            in "+-*/" -> {
                // pick top stack items
                val (a, b) = s.takeLast(2)
                // pop two items and then push based on op
                s = s.dropLast(2) + when(o) {
                    '+' -> a+b
                    '-' -> a-b
                    '*' -> a*b
                    '/' -> a/b
                    else -> 0  // else is required here
                }
            }
            // duplicate top stack item
            ':' -> s += s.last()
            // print top stack item
            '.' -> println(s.last())
            // open loop
            '(' -> {
                if(s.last()!=0)
                    // push to jump stack if top of data stack is nonzero
                    c+=i
                else {
                    // skip ahead
                    var z=0
                    do {
                        // seek to matching brace
                        if(p[i]=='(') z++ else if(p[i]==')') z--
                        i++
                    } while(z>0)
                    // ensure program counter doesn't go too far
                    i--
                }
            }
            // close loop
            ')' -> if(s.last()!=0) i=c.last() else c=c.dropLast(1)
        }
        // next character
        i++
    }
}

Probieren Sie es online aus!

Schnecke_
quelle