C koduna geçiş yapmak çok iyi kurulmuş bir alışkanlıktır. Sınıfları olan orijinal C (ve daha sonra Cfront adı verilen ilk C ++ uygulamaları ) bunu başarıyla yaptı. Lisp veya Scheme'in birçok uygulaması bunu yapıyor; örneğin Chicken Scheme , Scheme48 , Bigloo . Bazı insanlar Prolog'u C'ye çevirdi . Ve Mozart'ın bazı versiyonları da oldu (ve Ocaml bytecode'u C'ye derlemeye çalıştım ). J.Pitrat'ın yapay zeka CAIA sistemi de önyüklendi ve C kodunu üretti. Vala ayrıca GTK ile ilgili kod için C'ye çevirir. Queinnec'in kitabı Küçük Parçalarla Lisp C’ye çeviri hakkında bazı bölümler var
C'ye çevirirken ortaya çıkan sorunlardan biri, özyinelemeli çağrılardır . C standart (bir "argümanlarla atlama" için, yani bir C derleyicisi bunları düzgün tercüme olduğunu değil garantisi yok olmadan içinde bile, çağrı yığını yeme) bazı durumlarda, GCC (veya Clang ait / LLVM) son sürümlerini bu optimizasyon yapmak .
Diğer bir konu çöp toplamadır . Bazı uygulamalar sadece Boehm muhafazakar çöp toplayıcısını kullanır (ki bu C dostudur ...). Çöp toplamak istiyorsanız (bir kaç Lisp uygulamasının yaptığı gibi, örneğin SBCL gibi) bir kabus olabilir ( dlclose
Posix'te istersiniz ).
Yine bir başka konu ise birinci sınıf süreklilik ve çağrı / cc ile ilgilenmektir . Ancak akıllı hileler mümkündür (Tavuk Şeması'nın içine bakın). Çağrı yığınına erişmek bir çok püf noktası gerektirebilir (ancak GNU backtrace , vb. Bakınız ). Sürekliliğin ortogonal kalıcılığı (örneğin yığınlar veya iplikler) C'de zor olacaktır.
İstisnaların ele alınması çoğu zaman longjmp vb.
(Verilmiş C kodunuzda) uygun #line
direktifler oluşturmak isteyebilirsiniz . Bu çok sıkıcı ve çok çalışma gerektiriyor (örneğin, daha kolay bir şekilde gdb
hata ayıklama kodu üretmesini isteyeceksiniz).
Benim ERİME lispy alanı belirli bir dil (özelleştirmek veya genişletmek için GCC ) (şimdi ++ aslında fakir C) C çevrilmiştir. Kendi nesillerce kopyalayan çöp toplayıcı var. ( Qish veya Ravenbrook MPS tarafından ilginizi çekebilir ). Aslında, nesilsel GC, makine tarafından üretilen C kodunda elle yazılmış C kodundan daha kolaydır (çünkü C kodu üretecinizi yazma engeliniz ve GC makineniz için uyarlarsınız).
Orijinal C ++ koduna çeviren herhangi bir dil uygulamasını bilmiyorum , yani birçok STL şablonu kullanarak ve RAII deyimini dikkate alarak C ++ kodunu yayınlamak için bazı "derleme zamanı çöp toplama" tekniğini kullanarak . (Bir tanıyorsanız lütfen söyleyin).
Bugün komik olan, (mevcut Linux masaüstlerinde) C derleyicilerinin C'ye çevrilmiş etkileşimli bir üst düzey okuma-değerlendirme-baskı döngüsünü uygulamak için yeterince hızlı olabileceği : her kullanıcı için C kodu (birkaç yüz satır) göndereceksiniz etkileşim, fork
daha sonra yapacağınız paylaşılan bir nesneye derleyeceksiniz dlopen
. (MELT bunu hazırlar ve genellikle yeterince hızlıdır). Bütün bunlar saniyenin onda birini alabilir ve son kullanıcılar tarafından kabul edilebilir.
Mümkün olduğunda, özellikle C ++ derlemesi yavaş olduğu için C ++ 'a değil, C ++' a çevrilmesini tavsiye ederim.
Dilinizi uyguluyorsanız , libjit , GNU yıldırım , asmjit ve hatta LLVM veya GCCJIT gibi bazı JIT kütüphanelerini de (C kodu yaymak yerine) düşünebilirsiniz . C'ye çevirmek istiyorsanız, bazen tinycc kullanabilirsiniz : makine kodunu yavaşlatmak için üretilen C kodunu (bellekte bile) çok hızlı bir şekilde derler . Ancak genel olarak GCC gibi gerçek bir C derleyicisi tarafından yapılan optimizasyonlardan yararlanmak istiyorsunuz.
Dilinizi C'ye çevirirseniz , önce üretilen C kodunun tüm AST'sini bellekte oluşturduğunuzdan emin olun (bu, önce tüm bildirimleri, sonra tüm tanımları ve işlev kodunu oluşturmayı da kolaylaştırır). Bu şekilde bazı optimizasyonlar / normalizasyonlar yapabileceksiniz. Ayrıca, çeşitli GCC uzantılarıyla (örneğin bilgisayarlı goto'lar) ilgilenebilirsiniz. Muhtemelen büyük C fonksiyonları oluşturmaktan kaçınmak isteyeceksiniz - örneğin yüzbinlerce üretilen C satırı - (onları daha küçük parçalara ayırmanız daha iyi olacaktır) çünkü C derleyicileri optimize etmek çok büyük C fonksiyonlarından çok mutsuzdur (pratikte ve deneysel,gcc -O
büyük fonksiyonların derleme zamanı, fonksiyon kod büyüklüğünün karesiyle orantılıdır). Bu nedenle, oluşturulan C işlevlerinin boyutunu her biri birkaç bin satırla sınırlayın.
Hem Clang ( LLVM aracılığıyla ) hem de GCC ( libgccjit aracılığıyla ) C & C ++ derleyicilerinin, bu derleyiciler için uygun bazı iç gösterimler yayınlayacak bir yol sunduğuna dikkat edin, ancak bunu yapmak C (veya C ++) kodunu yayınlamaktan daha zor olabilir; ve her derleyiciye özgüdür.
C'ye çevrilecek bir dil tasarlıyorsanız, muhtemelen kendi dilinizle bir C karışımı oluşturmak için birkaç püf nokta (veya yapı) kullanmak istersiniz. DSL2011 makalem MELT: GCC Derleyicisine Gömülü Çevrilmiş Çevreye Özel Bir Dil size faydalı ipuçları vermelidir.