2016-04-08 32 views
2

Şartlar ile Lua'da küçük bir DSL kurmaya çalışıyorum.Bir Lua DSL için koşullara sahip olmak?

x = '0' 
function start() 
    return function() end 
end 

function set_x (v) 
    x = v 
    return function() end 
end 

function if_x (v) 
    if x == v then 
     print ("x = ", v) 
    else 
     print ("x != ", v) 
    end 
    return function() end 
end 

-- DSL here 
start { 
    set_x '10', 
    if_x '10' { print ('x is 10') }, 
    if_x '20' { print ('x is 20') } 
} 

Çıktı geçerli: x is 20 baskılı olmamasının sağlanması amacıyla

x =  10 
x is 10 
x != 20 
x is 20 

Nasıl zarif bir şekilde conditionals uygulamak? set_x'da bir global değişken belirlemeden ve if_x içinde kontrol etmeden bunu yapamadım, ancak bu çirkin görünüyor.

Herhangi bir ipucu?

Teşekkürler!

+1

Ve BTW, neyiniz normal olarak ** E ** DSL (gömülü DSL) olarak adlandırılır, çünkü varolan dil yapılarını kullanır. –

cevap

2

EDSL'nizin Lua'ya benzediğine bakmak zorundasınız; en gibi "normal" sözdizimi kullanılarak

if_x '20' { print ('x is 20') } 

Biz bunu yazabiliriz sorunlu deyimi teşrih izin verin: Ben sorunlu kısmını vitrin 1 = ekledik

if_x('20')({ 1 = print('x is 20') }) 

; dizinin inşası, durumunuzun no'lu raporuna bakılmaksızın baskı beyanının değerlendirilmesini gerektirir. Değil kadar güzel

function if_x (v) 
    if x == v then 
     print ("x = ", v) 
     return function (block) block[1]() end 
    else 
     print ("x != ", v) 
     return function() end 
    end 
end 

ama seni düşünmüyorum:

start { 
    set_x '10', 
    if_x '10' { function() print ('x is 10') end }, 
    if_x '20' { function() print ('x is 20') end } 
} 

sonra koşullu olarak çağrılabilir: Çalışma yapmak için

, aslında bir lambda gerek Bundan kurtulabilir, çünkü bir lambda ile sarılmamış herhangi bir ifadenin yürütülmesi gerekir. Koşul operatörünün kısa devre davranışıyla oynamayı deneyebilirsiniz, ancak daha sonra kodu daha fazla geçemezsiniz, çünkü her zaman işlev sınırlarında değerlendirilir.

See Live on Ideone

4

ör

x = '10' 

function if_x (v) 
    if x == v then 
    return function (s) 
     assert(loadstring(s))() 
    end 
    end 
    return function() end 
end 

if_x '10' [[print('x is 10')]] 
if_x '20' [[print('x is 20')]] 
+2

Detaylandırmak için: '[[x]]' Lua’daki "x" için alternatif bir sözdizimidir. Yani 'print ... 'satırları aslında çalışma zamanında Lua ayrıştırıcısına koşullu olarak beslenen dizelerdir. İşte bu cevap, değerlendirme problemini çözmektedir: 'if_x' işlevine veya ifadesinin sonucuna geçmeyen bir dizedir. İyi bir! :) –