2010-08-13 25 views
39

Son zamanlarda Makefiles'ten alternatif bir yapım sistemine çeviri yapıyorum. İşlevsel harita, filtre ve foreach yapılarını kullanarak bazı yerlerde oldukça kıllı Makyaj kodu gördüm. Bu beni şaşırttığından, bence senaryoları olabildiğince açıklayıcı olmalı diye düşünüyorum. Her neyse, bu bana şunu düşünmemi sağladı: Makefile dili (en yeni GNU yapımının spesifik olduğu söyleniyor) Turing tamamlandı mı?Makefiles Turing tamamlandı mı?

+1

Açıklama olmadan, bir bahsin çözülüp çözülmediğini soruyorum :) –

+0

Unix'te, tüylü bir sözdizimi var ve şaşırtıcı derecede güçlü. Bunun gibi çoğu şey Turing-complete. Yirmi yıl önce birinin bana bir mikro Turing makinesi gösterdiğinde şaşırmadım. –

+3

Dizelerin yapımı sırasında Turing makinesi de dahil olmak üzere istediğiniz herhangi bir şeye gömebilirsiniz. Teknik olarak bu noktada kayboldun. (Perl'leri Makefiles'imizde çağırırız.) –

cevap

40

Evet, bkz. this. Lambda olduktan sonra, hepsi oradan yokuş aşağı gidiyor. İşte

bir plagiarized Fibonacci örneği

Bu daha genelliği için bir temel oluşturmak için yeterli olmalıdır (Ben işe geri dönmeliyim, yoksa daha oynamak istiyorum.)

dec = $(patsubst .%,%,$1) 

not = $(if $1,,.) 

lteq = $(if $1,$(if $(findstring $1,$2),.,),.) 
gteq = $(if $2,$(if $(findstring $2,$1),.,),.) 
eq = $(and $(call lteq,$1,$2),$(call gteq,$1,$2)) 
lt = $(and $(call lteq,$1,$2),$(call not,$(call gteq,$1,$2))) 

add = $1$2 
sub = $(if $(call not,$2),$1,$(call sub,$(call dec,$1),$(call dec,$2))) 
mul = $(if $(call not,$2),$2,$(call add,$1,$(call mul,$1,$(call dec,$2)))) 
fibo = $(if $(call lt,$1,..),$1,$(call add,$(call fibo,$(call dec,$1)),$(call fibo,$(call sub,$1,..)))) 
fact = $(if $(call lt,$1,..),.,$(call mul,$1,$(call fact,$(call dec,$1)))) 

numeral = $(words $(subst .,. ,$1)) 

go = $(or $(info $(call numeral,$(call mul,$1,$1)) $(call numeral,$(call fibo,$1)) $(call numeral,$(call fact,$1))),$(call go,.$1)) 

_ := $(call go,) 

Bu, kareler, fibonacci sayıları ve faktörler yazdırır. Sayı boyutlarında 16 bitlik bir sınır var gibi görünüyor. Aylak.

+1

Bir kez lambdaya sahipseniz, sanırım size yineleme veren bir Y-birleştirici oluşturabilirsiniz. Dediğin gibi, oradan yokuş aşağı. –

+9

Bu harika. Ve korkutucu. Çoğunlukla korkutucu. –

+0

@Jorg Oleg harika ama korkutucu bir adam. Çoğunlukla korkutucu. Sahip olduğu diğer şeyleri oku. – deinst

6

Şimdi olumsuz bir cevap:

1) Recursively expanded variables

"özyinelemeli fonksiyon" anlamında özyinelemeli değildir:: GNU yineleme oluşturmak için bazı mekanizmalar aktif blok yapmak onlar tanımlanamaz kendileri açısından:

Actually make detects the infinite loop and reports an error. 

(Bu arada, bunları pratikte faydalı olabilir izin nasıl görmüyorum.)

2) Rule chaining

, özyinelemeli olamaz ya:

No single implicit rule can appear more than once in a chain. (...) 
This constraint has the added benefit of preventing any infinite loop 
in the search for an implicit rule chain. 

(benim Makefiles ayıklama bu süre boyunca zaman oldukça fazla kayıp - zor makefiles yapmak tüm diğer şeyler yanında sürdürmek.)

PS Son zamanlardaki bir proje için bu sınırlamayı -M seçeneğiyle kaldıran a patch to GNU make 3.82 yazdım (bkz. discussion). Benim için iyi çalışıyor.

+0

Bu ilginç, ancak her zaman $ (eval) gibi bir şeyin varlığında yinelemeli makroları algılayabilirse çok şaşırırım. –

İlgili konular