Phiên dịch dễ bay hơi


11

Phiên dịch dễ bay hơi

Dễ bay hơi là một esolang dựa trên ngăn xếp được tạo bởi A_ / a '_' / A chỉ có 8 hướng dẫn và đã hoàn tất. Tuy nhiên, điều này cũng không mang tính quyết định ... có nghĩa là các chương trình không phải lúc nào cũng cho cùng một đầu ra. Nhiệm vụ của bạn là diễn giải ngôn ngữ này.

Thông số kỹ thuật ngôn ngữ

Lấy từ trang esolang:

~: 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

Mọi thứ khác đều bị coi thường

Đầu vào

Lưu ý rằng các chương trình này có thể ngẫu nhiên thất bại

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

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

~:-:/

Đầu ra

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>

Có thể tìm thấy nhiều ví dụ khác, cũng như triển khai tham chiếu (sử dụng cái thứ hai, được tìm thấy trong (Khác) trình thông dịch python 3 ) tại https://esolangs.org/wiki/Voliverse

Chấm điểm

Đây là môn đánh gôn, vì vậy câu trả lời ngắn nhất bằng byte thắng

Bảng xếp hạng

Dưới đây là một Stack Snippet để tạo cả bảng xếp hạng thông thường và tổng quan về người chiến thắng theo ngôn ngữ.

Để đảm bảo rằng câu trả lời của bạn hiển thị, vui lòng bắt đầu câu trả lời của bạn bằng một tiêu đề, sử dụng mẫu Markdown sau:

# Language Name, N bytes

nơi Nlà kích thước của trình của bạn. Nếu bạn cải thiện điểm số của mình, bạn có thể giữ điểm số cũ trong tiêu đề, bằng cách đánh chúng qua. Ví dụ:

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

Nếu ở đó bạn muốn bao gồm nhiều số trong tiêu đề của mình (ví dụ: vì điểm của bạn là tổng của hai tệp hoặc bạn muốn liệt kê riêng các hình phạt cờ phiên dịch), hãy đảm bảo rằng điểm thực tế là số cuối cùng trong tiêu đề:

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

Bạn cũng có thể đặt tên ngôn ngữ thành liên kết sau đó sẽ hiển thị trong đoạn trích bảng xếp hạng:

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


2
Là phân chia có nghĩa là làm tròn về 0?
Grimmy

~đẩy một số nguyên, hoặc bất kỳ số nào?
mbomb007

1
Ngoài ra, tùy thuộc vào việc thực hiện, điều này có thể không thực sự không mang tính quyết định. Chắc chắn, trang esolang tuyên bố như vậy, nhưng đó chỉ là do cách liệt kê để đẩy 1, có thể chia cho số không. ~phải có khả năng đẩy số không, nếu không nó mang tính quyết định. Ngoài ra, RNG phải luôn có thể trả về 0 sau bất kỳ số 0 nào trong một hàng.
mbomb007

2
Không nên ~:-.~:/+.(~:/+.)bắt đầu đầu vào thứ hai từ 0 1 2 ...thay vì 1 2 3 ...? Các ~:-.sẽ cho kết quả 0 mà nó ra. Những thông dịch viên trên trang Esolang dường như xác nhận điều này ( ở đây là lần thứ hai ).
Kevin Cruijssen

2
Đề xuất thêm trường hợp kiểm tra:~:-.(~:/+.)
Night2

Câu trả lời:


6

05AB1E , 35 byte

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

Hãy thử trực tuyến!

Transpiles Mã dễ bay hơi đến 05AB1E, sau đó loại bỏ nó. *, +-có thể được để lại như nó vốn có. :, .)có tương đương một byte trực tiếp. Các lệnh khác mất một vài byte mỗi. Thật không may, 05AB1E không gặp sự cố khi chia cho 0, do đó, điều này thay vào đó được thực hiện bằng cách "thoát nếu có đỉnh stack == 0" có điều kiện.


1
Điều này làm việc chính xác cho các vòng lặp. Nếu tôi nhập trường hợp thử nghiệm thứ hai, nó dường như xuất hiện 01chính xác trước vòng lặp, nhưng sau đó nó bắt đầu xuất ra chương trình Biến động (đầu vào ẩn). Tôi thích D Doingõqchuỗi từ điển đó cho câu lệnh if, btw! :)
Kevin Cruijssen

1
@KevinCruijssen ví dụ dường như giả sử vòng lặp là một while peek, nhưng trong trình thông dịch tham chiếu thì nó là a while pop. Ví dụ có thể được sửa bằng cách thêm một số :( TIO ). Ngoài ra, mã của tôi có thể được thay đổi thành a while peekbằng cách thêm a D.
Grimmy

1
Cả hai thông dịch viên tham khảo từ Esolang vẫn xuất ra 0 1 2 3 ..., mặc dù. Tôi đã không nhìn vào mã nguồn của họ, nhưng chỉ thử cả hai.
Kevin Cruijssen

1
@KevinCruijssen Ồ, chức năng được đặt tên là pop nhưng thực sự là một cái nhìn trộm. Cực kỳ khó hiểu. Tôi đã thêm Dvào mã của tôi.
Grimmy

Lol .. Các tên dựng sẵn khó hiểu làm tôi nhớ đến Java replacevs replaceAll(cả hai đều thay thế tất cả các lần xuất hiện, nhưng replaceAllsử dụng biểu thức chính quy và các tên khác thì không). xD
Kevin Cruijssen

4

Julia 1.0 , 334 byte

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)

"Thông dịch viên" đầu tiên của tôi thuộc bất kỳ loại nào, nó dễ dàng hơn tôi mong đợi. Tôi đã chơi golf cơ bản, nhưng có lẽ còn nhiều chỗ hơn. Tôi đã làm cho nó in một không gian sau khi đầu ra cho. để mach ví dụ đầu ra. Phiên bản chưa được chỉnh sửa nằm trong tiêu đề tại liên kết TIO. Ví dụ sử dụng v("~:-:/").

+41 byte để sửa lỗi Night2 đã chỉ ra bằng cách thêm bộ đếm vòng lặp. Bây giờ tôi thấy tại sao transpiling là một lựa chọn tốt. Một trường hợp thử nghiệm tốt là ~:-.(~:/+.)(~:/+.())~:-.với đầu ra dự kiến0 0

Hãy thử trực tuyến!


3

Bùa mê runic , 266 264 byte

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͍

Hãy thử trực tuyến!

Do các giới hạn được tích hợp trong Runic, nó chỉ có thể hỗ trợ độ dài chương trình (và kích thước ngăn xếp) là ~ 50 1 . Các chương trình quá lớn sẽ đơn giản là thất bại. Nếu ngăn xếp phát triển quá lớn, nó sẽ báo lỗi SO!(không bắt buộc, nhưng tốt hơn là chấm dứt im lặng; tốn 24 byte). Nếu chương trình cố gắng chia cho 0, nó sẽ in /0!.

Lỗi được nối vào cuối đầu ra tiêu chuẩn vì Runic không có cách nào ghi vào STDERR.

Phiên bản này sẽ hỗ trợ các chương trình dài tùy ý, nhưng vẫn bị giới hạn ở một ngăn xếp ~ 90 (và do đó có lỗi trong kết quả thứ 2 của chương trình thử nghiệm đầu tiên) và đã không được đánh golf tốt (việc tăng độ dài lệnh giữa S͗}:S͗}͍:0%:yêu cầu một số khoảng cách bổ sung để có được các phần để xếp hàng, nhưng không gian thêm đó cũng cho phép nhiều hơn <cho kích thước ngăn xếp tối đa lớn hơn).

Ngoài ra, chương trình này sẽ tránh ~tạo ra số 0 và chương trình sẽ chấm dứt sau 1 triệu bước thực hiện (một biện pháp bảo vệ chống lại các vòng lặp vô hạn được tích hợp trong trình thông dịch Runic). Cũng bao gồm một vài byte để bỏ qua không gian NOP dư thừa và chạy lâu hơn một chút.

  1. Sự xì hơi quá khổ xảy ra tại (IP mana + 10) và kiểm tra mà tôi đã đặt cho ngăn xếp của Volility là sizeof(stack) < manavà có 5 IP hợp nhất và kết hợp mana của chúng (50 chữ cái đầu). Việc tăng giá trị đó đến giới hạn thực (+10) sẽ tốn thêm 2 byte và tôi rời khỏi logic golf thay vì chính xác.

Giải trình

Dòng chảy dễ bay hơi

  1. Chương trình bắt đầu ở khu vực màu xanh trung tâm hàng đầu dọc theo <<<<<và năm IP hợp nhất với nhau tạiy
  2. IP di chuyển sang bên trái, thiết lập ngăn xếp và đọc đầu vào và di chuyển đến phần màu lục lam
  3. IP di chuyển sang bên phải xuống dòng này kiểm tra char trên cùng trên ngăn xếp xem nó là lệnh gì. Dòng này tiếp tục ở bên phải xa hơn là có thể nhìn thấy. khi tìm thấy hướng dẫn chính xác, nó thực thi mã trên dòng bên dưới bên trái (bỏ qua các phần khác để quay lại màu lục lam qua màu xanh).
  4. Phần Magenta được thực thi trong khi ~hoặc :các lệnh bị lỗi trên Stack Overflow, phần màu vàng sẽ bị bỏ qua nếu ngăn xếp không quá đầy và trả về qua đường bao quanh thành màu xanh đậm.
  5. Xa về bên phải khi )tìm thấy các nhánh chương trình đến phần màu đỏ và di chuyển sang bên phải.
  6. Phần này xoay ngăn xếp lệnh sang phải cho đến khi (tìm thấy a (tiến hành màu xanh lá cây).
  7. Đối với mỗi bổ sung )được tìm thấy (tiến hành màu cam), ngăn xếp độ sâu ngăn xếp bị va đập và khi (tìm thấy a, ngăn xếp độ sâu ngăn xếp được bật một lần (tiến hành nhập lại màu xanh đậm và màu cam)
  8. Nếu ngăn xếp độ sâu trống tiếp tục theo màu xanh lá cây đến Bvà quay lại màu lục lam đến vòng phân tích cú pháp chính, nếu không thì bọc qua màu cam-> vàng-> đỏ (nhập lại vòng lặp đặt lại vòng lặp).
  9. Màu tím ở trên cùng bên phải xử lý phân chia, nếu giá trị để chia cho 0, phần màu nâu xử lý lỗi và chấm dứt. Nhập lại vòng lặp phân tích chính bằng cách bỏ qua phần màu lục lam.


2

JavaScript (V8) ,  178 172  171 byte

Chuyển mã sang JS. Có thể ném Z is not definedhoặc x is not definednếu mã cố gắng làm điều gì đó xấu.

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=[]))

Hãy thử chương trình trực tuyến đầu tiên!

Hãy thử chương trình trực tuyến thứ 2!

Hãy thử chương trình trực tuyến thứ 3!

Làm sao?

Mỗi hướng dẫn được dịch mã S.push(, theo sau là một mẫu cụ thể, theo sau là );.

Chúng tôi phải kiểm tra sự phân chia bằng 0 một cách rõ ràng bởi vì JS không đưa ra một chút chết tiệt nào về một hoạt động vô hại như vậy. :-p

char | Mã JS
------- + --------------------------------------
   ~ | S.push ( x = Math.random () * 1e5 | 0 );
   + | S.push ( 1 / (x + = S.pop (S.pop ()))? X: Z );
   - | S.push ( 1 / (x- = S.pop (S.pop ()))? X: Z );
   * | S.push ( 1 / (x * = S.pop (S.pop ()))? X: Z );
   / | S.push ( 1 / (x / = S.pop (S.pop ()))? X: Z );
   : | S.push ( x );
   . | S.push ( ); in (x );
   (| S.push ( ); trong khi (x) {(0 );
   ) | S.push ( )} (0 );

2

Java 8, 420 418 402 373 359 357 341 byte

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 byte nhờ @Grimy .
-16 byte nhờ @ceilingcat .

Hãy thử trực tuyến.

Giải trình:

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

1
new Random().nextInt()là 2 ngắn hơn (int)(Math.random()*1e5).
Grimmy

@Grimy Ah, quên tôi đã java.util.*nhập mà cho Stack. Cảm ơn! :)
Kevin Cruijssen

@ceilingcat Cảm ơn vì -16!
Kevin Cruijssen

Điều này có thể đi ngược lại một hoặc nhiều quy tắc đàng hoàng nhưng nếu bạn thay thế new Random().nextInt()bằng 5tất cả các testcase vẫn vượt qua.
trần mèo

@ceilingcat Vâng, nhưng 5không chính xác ngẫu nhiên ;) xkcd có liên quan
Kevin Cruijssen

2

C (gcc) cho 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);}

Hãy thử trực tuyến!

Đây là một JIT dịch trực tiếp các hướng dẫn dễ bay hơi sang ngôn ngữ máy x86_64 và thực thi mã. Nếu máy của bạn không có rdrandhướng dẫn, bạn có thể thay thế L"\xf0c70f50"bằng "Pj*X"" PRNG kém đồng nhất ". Để chuyển sang một thứ khác ngoài Linux, thay thế các tòa nhà trong printf()exit()các đốm màu và điều chỉnh các tham số thành mmap().

EDIT: Phiên bản này gọi printf()thay vì thực hiện một tập hợp con từ đầu.

EDIT2: Số nguyên được hỗ trợ hiện là 32 bit thay vì 64.

Hơi ít chơi gôn ...

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

1

Kotlin , 412 byte

Thật không may, tôi đã thua Java, nhưng tôi không muốn import java.util.Stack(và tôi không chắc nó sẽ thu hẹp khoảng cách nào.)

{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++}}

Ung dung

{ 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++
    }
}

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.