เขียนล่าม Clem


11

Clem เป็นภาษาการเขียนโปรแกรมแบบกองซ้อนที่มีฟังก์ชั่นชั้นหนึ่ง จุดประสงค์ของคุณคือการเขียนล่ามสำหรับภาษา Clem มันถูกต้องควรจะดำเนินการตัวอย่างทั้งหมดรวมอยู่ในการดำเนินการอ้างอิงที่มีอยู่ที่นี่

ภาษาเคล็ม

Clem เป็นภาษาโปรแกรมสแต็กที่มีฟังก์ชั่นชั้นหนึ่ง วิธีที่ดีที่สุดในการเรียนรู้ Clem คือการใช้clemล่ามโดยไม่มีข้อโต้แย้ง มันจะเริ่มต้นในโหมดโต้ตอบช่วยให้คุณสามารถเล่นกับคำสั่งที่มีอยู่ ในการรันโปรแกรมตัวอย่างให้พิมพ์clem example.clmโดยที่ example คือชื่อของโปรแกรม บทแนะนำสั้น ๆ นี้ควรจะเพียงพอสำหรับคุณในการเริ่มต้น

มีฟังก์ชั่นหลักสองประเภท ฟังก์ชั่นอะตอมมิกและฟังก์ชั่นสารประกอบ ฟังก์ชั่นผสมคือรายการที่ประกอบด้วยฟังก์ชั่นอื่น ๆ และฟังก์ชั่นอะตอมมิก โปรดทราบว่าฟังก์ชั่นผสมไม่สามารถมีตัวเอง

ฟังก์ชั่นของอะตอม

ชนิดแรกของฟังก์ชั่นของอะตอมเป็นคงที่ คงเป็นเพียงค่าจำนวนเต็ม ตัวอย่างเช่น -10 เมื่อล่ามพบค่าคงที่มันจะดันไปที่สแต็ก เรียกใช้clemตอนนี้ พิมพ์-10ที่พรอมต์ คุณควรเห็น

> -10
001: (-10)
>

ค่า001อธิบายถึงตำแหน่งของฟังก์ชันในสแต็กและ(-10) เป็นค่าคงที่ที่คุณเพิ่งป้อน ตอนนี้ป้อน+11ที่พรอมต์ คุณควรเห็น

> +11
002: (-10)
001: (11)
>

ขอให้สังเกตว่า(-10)ได้ย้ายไปยังตำแหน่งที่สองในกองซ้อนและ(11)ตอนนี้ครองตำแหน่งแรก นี่คือธรรมชาติของสแต็ก! คุณจะสังเกตเห็นว่า-เป็นคำสั่งลดลง เมื่อใดก็ตาม-หรือ+นำหน้าหมายเลขพวกเขาจะแสดงสัญลักษณ์ของตัวเลขนั้นและไม่ใช่คำสั่งที่เกี่ยวข้อง ทุกฟังก์ชั่นของอะตอมอื่น ๆ ที่มีคำสั่ง มีทั้งหมด 14:

@  Rotate the top three functions on the stack
#  Pop the function on top of the stack and push it twice
$  Swap the top two functions on top of the stack
%  Pop the function on top of the stack and throw it away
/  Pop a compound function. Split off the first function, push what's left, 
   then push the first function.
.  Pop two functions, concatenate them and push the result
+  Pop a function. If its a constant then increment it. Push it
-  Pop a function. If its a constant then decrement it. Push it
<  Get a character from STDIN and push it to the stack. Pushes -1 on EOF.
>  Pop a function and print its ASCII character if its a constant
c  Pop a function and print its value if its a constant
w  Pop a function from the stack. Peek at the top of the stack. While it is
   a non-zero constant, execute the function.

การพิมพ์คำสั่งที่พรอมต์จะดำเนินการตามคำสั่ง พิมพ์#ที่พรอมต์ (คำสั่งซ้ำ) คุณควรเห็น

> #
003: (-10)
002: (11)
001: (11)
> 

ขอให้สังเกตว่า (11) ถูกทำซ้ำ ตอนนี้ให้พิมพ์%ที่พรอมต์ (คำสั่งปล่อย) คุณควรเห็น

> %
002: (-10)
001: (11)
> 

ในการส่งคำสั่งไปยังสแต็กเพียงแค่ล้อมรอบมันในวงเล็บ พิมพ์(-)ที่พรอมต์ สิ่งนี้จะดันโอเปอเรเตอร์การลดลงไปยังสแต็ก คุณควรเห็น

> (-)
003: (-10)
002: (11)
001: (-)
> 

ฟังก์ชั่นแบบผสม

คุณอาจใส่หลายฟังก์ชั่นของอะตอมมิกไว้ในวงเล็บเพื่อสร้างฟังก์ชั่นผสม เมื่อคุณเข้าสู่ฟังก์ชั่นรวมที่พรอมต์มันจะถูกผลักไปที่กองซ้อน พิมพ์($+$)ที่พรอมต์ คุณควรเห็น

> ($+$)
004: (-10)
003: (11)
002: (-)
001: ($ + $)
>

ในทางเทคนิคทุกอย่างในสแต็กเป็นฟังก์ชั่นแบบผสม อย่างไรก็ตามฟังก์ชั่นสารประกอบบางอย่างในสแต็กประกอบด้วยฟังก์ชั่นอะตอมมิกเดียว (ในกรณีนี้เราจะพิจารณาว่าเป็นฟังก์ชั่นอะตอมมิกเพื่อความสะดวก) เมื่อจัดการกับฟังก์ชั่นผสมบนสแต็ค.คำสั่ง (การต่อข้อมูล) จะมีประโยชน์บ่อยครั้ง พิมพ์.ทันที คุณควรเห็น

> . 
003: (-10)
002: (11)
001: (- $ + $)
> 

ขอให้สังเกตว่าฟังก์ชั่นที่หนึ่งและที่สองในสแต็กถูกต่อกันและฟังก์ชั่นที่สองในสแต็คมาก่อนในรายการผลลัพธ์ ในการดำเนินการฟังก์ชั่นที่อยู่ในสแต็ก (ไม่ว่าจะเป็นอะตอมหรือสารประกอบ) เราจะต้องออกwคำสั่ง (ในขณะที่) wคำสั่งจะปรากฏฟังก์ชั่นครั้งแรกในกองและดำเนินการซ้ำ ๆ ตราบใดที่ฟังก์ชั่นที่สองในสแต็คเป็นที่ไม่ใช่ศูนย์อย่างต่อเนื่อง wพยายามที่จะคาดการณ์สิ่งที่จะเกิดขึ้นถ้าเราพิมพ์ wตอนนี้พิมพ์ คุณควรเห็น

> w
002: (1)
001: (0)
> 

นั่นคือสิ่งที่คุณคาดหวัง มีการเพิ่มตัวเลขสองตัวที่อยู่ด้านบนสุดของสแต็กและผลรวมจะยังคงอยู่ ลองอีกครั้ง ครั้งแรกที่เราจะลดลงเป็นศูนย์และผลักดัน 10 %10โดยการพิมพ์ คุณควรเห็น

> %10
002: (1)
001: (10)
> 

ตอนนี้เราจะพิมพ์ฟังก์ชั่นทั้งหมดในนัดเดียว แต่เราจะเพิ่มส่วนพิเศษ%ตอนท้ายเพื่อกำจัดศูนย์ พิมพ์(-$+$)w%ที่พรอมต์ คุณควรเห็น

> (-$+$)w%
001: (11)
> 

(โปรดทราบว่าอัลกอริทึมนี้ใช้งานได้หากค่าคงที่แรกบนสแต็กเป็นค่าบวก)

เงื่อนไข

ปัจจุบันมีเงื่อนไข พวกเขาส่วนใหญ่น้ำตาล syntactic แต่จะมีประโยชน์มาก เมื่อล่ามพบสตริงสตริงนั้นจะผลักอักขระแต่ละตัวจากสุดท้ายไปยังอันดับแรกลงบนสแต็ก พิมพ์%เพื่อปล่อย 11 จากตัวอย่างก่อนหน้า ตอนนี้พิมพ์0 10 "Hi!"พรอมต์ 0จะแทรกเทอร์มิโมฆะและ10จะแทรกตัวละครใหม่เส้น คุณควรเห็น

> 0 10 "Hi!"
005: (0)
004: (10)
003: (33)
002: (105)
001: (72)
> 

พิมพ์(>)wเพื่อพิมพ์อักขระจากสแต็กจนกว่าเราจะพบกับ NULL terminator คุณควรเห็น

> (>)w
Hi!
001: (0)
> 

สรุปผลการวิจัย

หวังว่ามันจะเพียงพอที่จะให้คุณเริ่มต้นกับล่าม การออกแบบภาษาควรตรงไปตรงมา แจ้งให้เราทราบหากมีสิ่งใดที่ไม่ชัดเจนอย่างยิ่ง :) มีบางสิ่งที่ถูกทิ้งไว้โดยเจตนาที่คลุมเครือ: ค่าต้องลงนามและอย่างน้อย 16 บิตสแต็กจะต้องมีขนาดใหญ่พอที่จะเรียกใช้โปรแกรมอ้างอิงทั้งหมดเป็นต้น ออกมาที่นี่เพราะสเปคภาษาเป่าเต็มรูปแบบจะมีขนาดใหญ่โพสต์ห้าม (และฉันยังไม่ได้เขียนหนึ่ง: P) เมื่อมีข้อสงสัยเลียนแบบการดำเนินการอ้างอิง

หน้า esolangs.org สำหรับ Clem

การดำเนินการอ้างอิงใน C


คุณบอกว่าคุณยังไม่ได้เขียนข้อกำหนดภาษา ฉันเข้าใจแล้วว่าคุณเป็นผู้สร้างภาษาหรือไม่
COTO

@COTO ถูกต้อง ฉันสร้างภาษา
Orby

5
คำถามที่สำคัญมาก: คุณออกเสียงว่า "klem" หรือ "see-lem" หรือไม่?
Martin Ender

4
@ MartinBüttner: "klem" :)
Orby

2
คุณอาจต้องการระบุทิศทางที่คำสั่ง @ หมุน 3 ฟังก์ชันยอดนิยม (001 -> 002 -> 003 -> 001, หรือ 003 -> 002 -> 001 -> 003)
kwokkie

คำตอบ:


1

Haskell, 931 921 875

นี่ยังไม่สมบูรณ์นักกอล์ฟ แต่มันอาจจะไม่เคย ถึงกระนั้นมันก็สั้นกว่าโซลูชันอื่น ๆ ทั้งหมด ฉันจะตีกอล์ฟนี้อีกในไม่ช้า ฉันไม่รู้สึกอยากเล่นกอล์ฟมากกว่านี้

อาจมีข้อผิดพลาดเล็กน้อยบางอย่างเพราะฉันไม่ได้เล่นกับการใช้งานอ้างอิง C

วิธีการแก้ปัญหานี้ใช้ประเภทStateT [String] IO ()ในการจัดเก็บโปรแกรม clem "runnable" โปรแกรมส่วนใหญ่เป็นตัวแยกวิเคราะห์ซึ่งวิเคราะห์คำว่า "โปรแกรมที่รันได้"

เพื่อที่จะเรียกใช้การใช้งานr "<insert clem program here>"นี้

import Text.Parsec
import Control.Monad.State
import Control.Monad.Trans.Class
import Data.Char
'#'%(x:y)=x:x:y
'%'%(x:y)=y
'@'%(x:y:z:w)=y:z:x:w
'$'%(x:y:z)=y:x:z
'/'%((a:b):s)=[a]:b:s
'+'%(a:b)=i a(show.succ)a:b
'.'%(a:b:c)=(a++b):c
_%x=x
b=concat&between(s"(")(s")")(many$many1(noneOf"()")<|>('(':)&((++")")&b))
e=choice[s"w">>c(do p<-t;let d=h>>= \x->if x=="0"then a else u p>>d in d),m&k,s"-">>(m&(' ':)&k<|>c(o(\(a:b)->i a(show.pred)a:b))),s"c">>c(do
 d<-t
 i d(j.putStr.show)a),o&(++)&map(show.ord)&between(s"\"")(s"\"")(many$noneOf"\""),(do
 s"<"
 c$j getChar>>=m.show.ord),(do
 s">"
 c$do
 g<-t
 i g(j.putChar.chr)a),m&b,o&(%)&anyChar]
k=many1 digit
i s f g|(reads s::[(Int,String)])>[]=f$(read s::Int)|0<1=g
t=h>>=(o tail>>).c
c n=return n
a=c()
h=head&get
(&)f=fmap f
m=o.(:)
o=modify
u=(\(Right r)->r).parse(sequence_&many e)""
r=(`runStateT`[]).u
s=string
j=lift

5

Python 1684 1281ตัวอักษร

ทำทุกสิ่งพื้นฐานเกี่ยวกับกอล์ฟให้เรียบร้อย มันรันโปรแกรมตัวอย่างทั้งหมดและจับคู่เอาต์พุตอักขระต่ออักขระ

import sys,os,copy as C
L=len
S=[]
n=[S]
Q=lambda:S and S.pop()or 0
def P(o):
 if o:n[0].append(o)
def X():x=Q();P(x);P(C.deepcopy(x))
def W():S[-2::]=S[-1:-3:-1]
def R():a,b,c=Q(),Q(),Q();P(a);P(c);P(b)
def A(d):
 a=Q()
 if a and a[0]:a=[1,a[1]+d,lambda:P(a)]
 P(a)
def V():
 a=Q();P(a)
 if a and a[0]-1and L(a[2])>1:r=a[2].pop(0);P(r)
def T():
 b,a=Q(),Q()
 if a!=b:P([0,0,(a[2],[a])[a[0]]+(b[2],[b])[b[0]]])
 else:P(a);P(b)
def r():a=os.read(0,1);F(ord(a)if a else-1)
def q(f):
 a=Q()
 if a and a[0]:os.write(1,(chr(a[1]%256),str(a[1]))[f])
def e(f,x=0):f[2]()if f[0]+f[1]else([e(z)for z in f[2]]if x else P(f))
def w():
 a=Q()
 while a and S and S[-1][0]and S[-1][1]:e(a,1)
def Y():n[:0]=[[]]
def Z():
 x=n.pop(0)
 if x:n[0]+=([[0,0,x]],x)[L(x)+L(n)==2]
D={'%':Q,'#':X,'$':W,'@':R,'+':lambda:A(1),'-':lambda:A(-1),'/':V,'.':T,'<':r,'>':lambda:q(0),'c':lambda:q(1),'w':w,'(':Y,')':Z}
def g(c):D[c]()if L(n)<2or c in'()'else P([0,1,D[c]])
N=['']
def F(x):a=[1,x,lambda:P(a)];a[2]()
def E():
 if'-'==N[0]:g('-')
 elif N[0]:F(int(N[0]))
 N[0]=''
s=j=""
for c in open(sys.argv[1]).read()+' ':
 if j:j=c!="\n"
 elif'"'==c:E();s and map(F,map(ord,s[:0:-1]));s=(c,'')[L(s)>0]
 elif s:s+=c
 elif';'==c:E();j=1
 else:
    if'-'==c:E()
    if c in'-0123456789':N[0]+=c
    else:E();c in D and g(c)

ทดสอบ :

รวบรวมclemint.py , clemtest_data.py , clemtest.pyและรวบรวมไบนารีลงในไดเรกทอรีและเรียกใช้clemclemtest.py

การแพร่กระจาย :

รุ่น ungolfed มากที่สุดคือคนนี้ ตามด้วยสิ่งนั้น

Sเป็นสแต็กหลัก แต่ละรายการของสแต็กเป็น 3 รายการหนึ่งใน:

Constant: [1, value, f]
Atomic: [0, 1, f]
Compound: [0, 0, fs]

สำหรับค่าคงที่fคือฟังก์ชันที่เพิ่มค่าคงที่ลงบนสแต็ก สำหรับ atmoics ที่fเป็นฟังก์ชั่นที่รันหนึ่งของการดำเนินงาน (เช่น-, +) สำหรับสารประกอบfsคือรายการของรายการ

xecรันรายการ ถ้ามันเป็นค่าคงที่หรืออะตอมมันก็แค่รันฟังก์ชัน ถ้าเป็นสารประกอบถ้ายังไม่มีการเรียกซ้ำมันจะดำเนินการแต่ละฟังก์ชัน ดังนั้นการดำเนินการ(10 20 - 30)จะดำเนินการแต่ละฟังก์ชั่น10, 20, -และ30ทิ้ง10 19 30ในกอง หากมีการเรียกซ้ำแล้วมันก็แค่กดฟังก์ชั่นผสมลงบนสแต็ค ตัวอย่างเช่นเมื่อมีการดำเนิน(10 20 (3 4) 30)ผลที่ควรจะเป็นไม่ได้10 20 (3 4) 3010 20 3 4 30

การทำรังค่อนข้างยุ่งยาก คุณทำอะไรในขณะอ่านหนังสือ(1 (2 (3 4)))? การแก้ปัญหาคือการมีกองสแต็ค ในแต่ละระดับการซ้อนสแต็กใหม่จะถูกพุชบนสแต็กของสแต็กและการดำเนินการพุชทั้งหมดจะไปยังสแต็กนี้ นอกจากนี้หากมีการซ้อนกันฟังก์ชันอะตอมจะถูกผลักแทนการดำเนินการ ดังนั้นถ้าคุณเห็น10 20 (- 30) 40, 10ถูกผลักจากนั้น20แล้วสแต็คใหม่จะถูกสร้างขึ้น-และ30ถูกผลักลงบนสแต็คใหม่และ)ปรากฏออกกองใหม่เปลี่ยนมันเป็นรายการและผลักดันมันลงบนสแต็คระดับหนึ่งลง จับendnest() )มันค่อนข้างยุ่งยากเนื่องจากมีกรณีพิเศษเมื่อมีเพียงรายการเดียวเท่านั้นที่ถูกผลักออกไปและเราผลักกลับไปที่สแต็กหลัก นั่นคือ(10)ควรผลักดันค่าคงที่10ไม่ใช่คอมโพสิตที่มีค่าคงที่หนึ่งเนื่องจากแล้ว-และ+ไม่ทำงาน ฉันไม่แน่ใจว่านี่เป็นหลักการ แต่เป็นวิธีการทำงาน ...

ล่ามของฉันเป็นตัวประมวลผลแบบอักขระต่ออักขระ - มันไม่ได้สร้างโทเค็นดังนั้นตัวเลขสตริงและความคิดเห็นค่อนข้างน่ารำคาญที่จะจัดการ มีสแต็กแยกต่างหากNสำหรับหมายเลขที่กำลังถูกประมวลผลและทุกครั้งที่มีการประมวลผลอักขระที่ไม่ใช่ตัวเลขฉันต้องโทรendnum()เพื่อดูว่าฉันควรกรอกหมายเลขนั้นก่อนและวางลงในสแต็กหรือไม่ ไม่ว่าเราจะอยู่ในสตริงหรือข้อคิดเห็นถูกติดตามโดยตัวแปรบูลีน เมื่อสตริงถูกปิดมันจะผลักอวัยวะภายในทั้งหมดออกจากสแต็ก ตัวเลขติดลบต้องการการจัดการเป็นพิเศษเช่นกัน

นั่นเป็นเรื่องเกี่ยวกับภาพรวม ส่วนที่เหลือได้รับการดำเนินการทั้งหมดที่สร้างอินและทำให้แน่ใจว่าจะทำสำเนาลึกลงไปใน+, และ-#


รุ่งโรจน์! คุณสนุกไหม? :)
Orby

@Orby: ฉันแน่ใจ! มันเป็นภาษาที่น่าสนใจแปลก ๆ อย่างหนึ่ง ฉันหวังว่าฉันจะได้รับล่ามที่ <1k ไม่แน่ใจว่าสิ่งที่คาดหวังจากการส่งอื่น ๆ
Claudiu

4

C 837

ขอบคุณ @ceilingcat สำหรับการค้นหารุ่นที่ดีกว่า (และสั้นกว่า)

สิ่งนี้จะถือว่าทุกอย่างเป็นสตริงอย่างง่าย - รายการสแต็กทั้งหมดเป็นสตริงแม้ค่าคงที่จะเป็นสตริง

#define Q strcpy
#define F(x)bcopy(b,f,p-b);f[p-b-x]=!Q(r,p);
#define C(x,y)Q(S[s-x],S[s-y]);
#define N[9999]
#define A Q(S[s++]
#define D sprintf(S[s++],"%d"
#define G(x)}if(*f==x){
#define H(x)G(x)s--;
#define R return
#define Z(x)T(t,u,v)-1||putchar(x);H(
char S N N;s;c;T(b,f,r)char*b,*f,*r;{char*p;strtol(b+=strspn(b," "),&p,0);if(p>b){F(0)R 1;}if(c=*b==40){for(p=++b;c;)c+=(*p==40)-(*p++==41);F(1)R-1;}p++;F(0)*r*=!!*b;R 0;}*P(char*p){if(*p==34)R++p;char*r=P(p+1);D,*p);R r;}E(char*x){char*p,c N,f N,r N,t N,u N,v N;for(Q(c,x);*c;Q(c,p)){Q(t,S[s-1]);if(T(c,f,p=r))A,f);else{{G(64)C(0,1)C(1,2)C(2,3)C(3,0)G(35)A,t);G(36)C(0,2)C(2,1)C(1,0)H(37)H(47)T(t,u,v);*v&&A,v);A,u);H(46)strcat(strcat(S[s-1]," "),t);H(43)D,atoi(t)+1);H(45)D,atoi(t)-1);G(60)D,getchar());H(62)Z(atoi(u))99)Z(*u)119)for(Q(u,t);atoi(S[s-1]);)E(u);G(34)p=P(p);}}}}

ลองออนไลน์!

เวอร์ชันต้นฉบับของฉันที่ตีกอล์ฟน้อยกว่า (ต่างจากเวอร์ชัน golfed ที่นี่พิมพ์สแต็กเมื่อมันจบลงถ้ามันไม่ว่างเปล่าและรับพารามิเตอร์ -e เพื่อให้คุณสามารถระบุสคริปต์บนบรรทัดคำสั่งแทนที่จะอ่านจากไฟล์):

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define FIRST_REST(x) memcpy(first, b, p - b); first[p - b - x] = '\0'; strcpy(rest, p);
#define COPY(dest,src) strcpy(stack[size + dest], stack[size + src]);
char stack[9999][9999]; int size = 0;
int token(char *b, char *first, char *rest)
{
    while (*b == 32) b++;
    char *p; int x = strtol(b, &p, 0);
    if (p > b) { FIRST_REST(0) return 1; }
    if (*b == '(') { int c = 1; for (p = ++b; c; ++p) c += (*p == '(') - (*p == ')'); FIRST_REST(1) return -1; }
    p++; FIRST_REST(0) if (!*b) *rest = '\0'; return 0;
}
char *push(char *pointer)
{
    if (*pointer == '\"') return pointer+1;
    char *result = push(pointer+1);
    sprintf(stack[size++], "%d", *pointer);
    return result;
}
void eval(char *x)
{
    char program[9999], first[9999], rest[9999], tos[9999], tmp1[9999], tmp2[9999];
    char *pointer;
    for (strcpy(program, x); *program; strcpy(program, pointer))
    {
        *stack[size] = '\0';
        strcpy(tos, stack[size-1]);
        if (token(program, first, rest))
        {
            pointer = rest;
            strcpy(stack[size++], first);
        }
        else
        {
            pointer = rest;
            if (*first == '@'){
                COPY(0, -1) COPY(-1, -2) COPY(-2, -3) COPY(-3, 0) }
            if (*first == '#')
                strcpy(stack[size++], tos);
            if (*first == '$'){
                COPY(0, -2) COPY(-2, -1) COPY(-1, 0) }
            if (*first == '%')
                size--;
            if (*first == '/'){
                size--; token(tos, tmp1, tmp2); if (*tmp2) strcpy(stack[size++], tmp2); strcpy(stack[size++], tmp1); }
            if (*first == '.'){
                size--; strcat(stack[size - 1], " "); strcat(stack[size - 1], tos); }
            if (*first == '+'){
                size--; sprintf(stack[size++], "%d", atoi(tos) + 1); }
            if (*first == '-'){
                size--; sprintf(stack[size++], "%d", atoi(tos) - 1); }
            if (*first == '<')
                sprintf(stack[size++], "%d", getchar());
            if (*first == '>'){
                size--; if (token(tos, tmp1, tmp2) == 1) putchar(atoi(tmp1)); }
            if (*first == 'c'){
                size--; if (token(tos, tmp1, tmp2) == 1) printf("%s", tmp1); }
            if (*first == 'w'){
                size--; strcpy(tmp1, tos); while (atoi(stack[size - 1])) eval(tmp1); }
            if (*first == '\"')
                pointer=push(pointer);
        }
    }
}
int main(int argc, char **argv)
{
    char program[9999] = "";
    int i = 0, comment = 0, quote = 0, space = 0;
    if (!strcmp(argv[1], "-e"))
        strcpy(program, argv[2]);
    else
    {
        FILE* f = fopen(argv[1], "r");
        for (;;) {
            char ch = fgetc(f);
            if (ch < 0) break;
            if (!quote) {
                if (ch == '\n') comment = 0;
                if (ch == ';') comment = 1;
                if (comment) continue;
                if (ch <= ' ') { ch = ' '; if (space++) continue; }
                else space = 0;
            }
            if (ch == '\"') quote = 1 - quote;
            program[i++] = ch;
        }
        fclose(f);
    }
    eval(program);
    for (int i = 0; i < size; i++) printf("%03d: (%s)\r\n",size-i,stack[i]);
    return 0;
}

ดี! น่าประทับใจที่คุณเอาชนะโซลูชัน Python ใน C. ฉันต้องอัปโหลดเวอร์ชันที่สั้นกว่าของฉันฉันจัดการเพื่อกำจัด 60 ไบต์หรือดังนั้น .. ฉันยังสงสัยว่ามีวิธีการที่แตกต่างกันซึ่งจะให้ผลน้อยกว่า 1,000 ตัวอักษร
Claudiu

@Claudiu ฉันก็คิดอย่างนั้นเหมือนกัน - แต่ฉันไม่สามารถหาวิธีได้
Jerry Jeremiah
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.