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 ( dlclosePosix'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 #linedirektifler oluşturmak isteyebilirsiniz . Bu çok sıkıcı ve çok çalışma gerektiriyor (örneğin, daha kolay bir şekilde gdbhata 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, forkdaha 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 -Obü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.