BlockScript - 535
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
BlockScript เป็นภาษาสปาเก็ตตี้เรื่องไม่สำคัญที่ฉันสร้างขึ้นสำหรับความท้าทายนี้โดยเฉพาะ ล่ามฐานblockscript.c
โปรแกรมตัวอย่าง (พิมพ์หมายเลข Fibonacci 15 หมายเลขแรก):
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
ล่ามจะอ่านทั้งซอร์สโค้ดและอินพุตโปรแกรมจากอินพุตมาตรฐานตามลำดับนั้น ซึ่งหมายความว่าการเรียกใช้ล่ามภายในล่ามภายในล่ามเพียงคัดลอกและวาง:
# Level 1
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 2
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 3
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
เช่นเดียวกับภาพยนตร์Inceptionคุณแทบจะไม่สามารถเจาะลึกลงไปกว่าสามระดับ มันไม่ใช่เรื่องของเวลา แต่เป็นเรื่องของพื้นที่ BlockScript มีหน่วยความจำรั่วไหลอย่างมากมายและสิ่งนี้เกี่ยวข้องกับวิธีการออกแบบภาษาของตัวเอง
การอ้างอิงภาษา:
รับล่ามที่นี่
ใน BlockScript "stack" ไม่ใช่อาเรย์ที่ถูกเขียนทับโดยการดำเนินการที่ตามมาอย่างที่คุณอาจคุ้นเคย มันถูกนำมาใช้จริงเป็นรายการเชื่อมโยงที่ไม่เปลี่ยนรูปและสแต็คยังคงอยู่ในช่วงระยะเวลาของโปรแกรม นอกจากนี้ไม่มีตัวดำเนินการ (ยกเว้น@
) ลบค่าออกจากสแต็ก อย่างไรก็ตามการแก้ไขสแต็กจะมีผลกับบล็อกที่เกิดขึ้นเท่านั้น
การเลือกค่า
a
ตลอด z
ดึงรายการ 0-25 จากสแต็กและผลักไปที่สแต็ก a
อ้างถึงส่วนหัวหรือรายการที่ผลักดันล่าสุดของสแต็ก
A
ตลอด Z
ดึงรายการ 0-25 ของเฟรมปัจจุบันแล้วดันไปที่สแต็ก
[
เปิด "frame" เพื่อเลือกรายการจากการอ้างอิงสแต็ก (ดูด้านล่าง) ที่ส่วนหัวของสแต็ก [
ไม่จำเป็นต้องมีการจับคู่]
แต่เฟรมถูกกำหนดขอบเขตไว้เล็กน้อย ใน BlockScript "ขอบเขต" ถูกกำหนดโดยเครื่องหมายวงเล็บปีกกา ( {
... }
) ที่ฟอร์มบล็อก ดังนั้นการเปิดเฟรมภายในบล็อกจะไม่มีผลกับโค้ดภายนอกบล็อก
]
ปิดเฟรมปัจจุบันกลับไปที่เฟรมก่อนหน้า (ถ้ามี)
บล็อก
{
... }
สร้าง "บล็อก" และกดไปที่สแต็ก ภายในบล็อกสแต็กจะเริ่มต้นในสิ่งที่อยู่ก่อนหน้าบล็อกยกเว้นสแต็กของผู้โทรจะถูกผลักด้านบน สแต็กจะคงอยู่และไม่เปลี่ยนรูปใน BlockScript ดังนั้นบล็อกจึงปิด สำนวน{[
หมายถึงเปิดบล็อกจากนั้นเปิดเฟรมเพื่อเริ่มเลือกอาร์กิวเมนต์ (ใช้A
ผ่านZ
) ค่าส่งคืนของบล็อกคือส่วนหัวของสแต็กเมื่อ}
ถึง
ตัวอย่าง:
'3 '2 '1 {[ b. d. f. B. C. D. A! } 'D 'C 'B d!;
งานพิมพ์123BCD123DCB123BCD123DCB…
นี้ ตัวอักษรตัวเล็กอ้างถึงค่าสแต็กในขณะที่ตัวอักษรตัวพิมพ์ใหญ่อ้างถึงข้อโต้แย้ง (เนื่องจากเฟรมถูกตั้งค่าเป็นสแต็กของผู้โทร) A!
ใช้หัวของผู้โทร (ซึ่งรับประกันว่าจะเป็นบล็อกที่ถูกเรียก) และเรียกมัน หากคุณสงสัยว่าทำไมมันถึงกลับกันBCD
ทุกครั้งมันเป็นเพราะB. C. D.
ผลักดันข้อโต้แย้งเหล่านั้นในลำดับย้อนกลับทันทีก่อนที่บล็อกจะเรียกตนเอง
!
เรียกบล็อก กดค่าส่งคืนไปยังสแต็ก
การอ้างอิงสแต็ก
&
สร้างการอ้างอิงสแต็กและกดไปที่สแต็ก คิดว่านี่เป็น "super-cons" เพราะมันจะนำทุกรายการในสแต็คอย่างมีประสิทธิภาพและสร้าง "tuple" ออกมาจากมัน สำนวน&[
หมายถึงว่าสิ่งที่a
, b
, c
เรียกว่าก่อนหน้านี้สามารถเข้าถึงได้ด้วยA
, B
, C
(สำหรับส่วนที่เหลือของบล็อกหรือจนกว่า]
จะพบ)
ส่วนหนึ่งเป็นเพราะ&
ค่ามากกว่าที่ปกติต้องการ BlockScript รั่วหน่วยความจำโดยการออกแบบ
@
สลับไปยังสแต็กที่ชี้ไปตามการอ้างอิงสแต็a
ก ตัวดำเนินการนี้ค่อนข้างแปลก แต่ตัวแปลภาษาด้วยตนเองของ BlockScript ใช้สองสามครั้งเพื่อหลีกเลี่ยงการกดอาร์กิวเมนต์เดียวกันสองครั้ง ผลกระทบของ@
(หรือการดำเนินการสแต็กใด ๆ สำหรับเรื่องนั้น) จะถูก จำกัด อยู่ที่บล็อกที่ถูกเรียกใช้ นอกจากนี้เฟรมยังไม่ได้รับผลกระทบ@
ดังนั้นจึงสามารถใช้เฟรมเพื่อจับค่าที่คุณต้องการหลังจากสลับสแต็ก
การแสดงออกตามเงื่อนไข
I / O
หมายเหตุ: อินพุตและเอาต์พุตเสร็จสิ้นใน UTF-8 "ตัวอักษร" เป็นจำนวนเต็มที่สอดคล้องกับดัชนี Unicode
ตัวอักษรจำนวนเต็ม / ตัวอักษร
หมายเหตุ: จำนวนเต็มและตัวอักษรเป็นสิ่งเดียวกันใน BlockScript
'c
ผลักดันตัวละครค
[0-9] +
กดจำนวนเต็มทศนิยม
คณิตศาสตร์
ตัวดำเนินการเหล่านี้ใช้งานได้กับค่าจำนวนเต็มเท่านั้น
+
คำนวณb
+ a
(ผลักผลลัพธ์ แต่ไม่ทิ้งค่าใดค่าหนึ่ง)
-
คำนวณb
- a
.
*
Compute *b
a
/
คำนวณb
/ a
(การหารจำนวนเต็มปัดเศษไปทางอนันต์ลบ)
%
คำนวณb
% a
(โมดูลัสจำนวนเต็ม; ปัดเศษไปทางอนันต์ลบ)
ผู้ประกอบการเชิงสัมพันธ์
ตัวดำเนินการเหล่านี้ใช้งานได้กับค่าจำนวนเต็มเท่านั้น
<
ถ้าb
น้อยกว่าa
ให้กด 1 และกด 0 อีกครั้ง
>
=
เบ็ดเตล็ด
#
แสดงความคิดเห็นถึงจุดสิ้นสุดของบรรทัด
- โปรแกรมจะต้องจบด้วย
;
- อักขระอื่น ๆ ทั้งหมดจะถูกละเว้น
/usr/bin/cat
) แล้วทัวริงสมบูรณ์ไหม