2009-05-27 9 views
32

Existe-t-il des compilateurs de code natif pour Lisp? Dans quelle mesure peut-il même être compilé, avec toute sa nature dynamique, la collecte des ordures, les macros et quoi d'autre?Y a-t-il des compilateurs de code natif Lisp?

+2

Et de penser jusqu'à présent, j'ai pensé que LISP a été interprété. –

+1

Parlez-vous de Common Lisp, exclusivement? –

+2

@Amit, oui et non. Je veux trouver un moyen de générer (assez petit pour être pratique) des fichiers Windows * .exe pour écrire des utilitaires jetables à usage unique, comme des convertisseurs de fichiers, que je pourrais ensuite donner à quelqu'un d'autre au travail à utiliser sans les supplier pour installer Lisp sur leurs machines (d'autant plus qu'ils sont toujours fâchés contre moi après leur avoir fait installer Python). Pour cela, je préférerais Common Lisp car cela me semble plus "pratique". D'un autre côté, j'aimerais aussi connaître les compilateurs de Scheme (ou de n'importe quel autre), pour voir la grande image. – Headcrab

Répondre

53

De nombreux compilateurs Lisp sont compilés en code 'natif'. «Natif» signifie ici «code machine» (x86 en mode 32 bits ou 64 bits, PowerPC, SPARC, ...).

Autres questions:

  • peuvent compilateurs 'code non natif' générer des fichiers exécutables unique? -> Oui.

  • Les compilateurs 'code natif' peuvent-ils générer des fichiers exécutables à un seul fichier? -> Oui.

  • comment «natif» est «natif»? -> Le système Lisp aura la plupart du temps sa propre structure de données interne (classes CLOS), sa propre gestion des erreurs ('conditions'), sa propre gestion de la mémoire (garbage collection), ses propres bibliothèques, ...

  • Lisp peut-il fonctionner sans GC? -> Habituellement non. Il y a des exceptions.

  • qu'en est-il de la taille de l'application? -> Par défaut, les moyens simples de générer une application Lisp conduisent souvent à de grands exécutables.Les exécutables incluent le Lisp entier, y compris sa bibliothèque, les noms de tous les symboles, les informations sur les listes d'arguments aux fonctions, le compilateur, le débogueur, les informations d'emplacement du code source, et plus encore. Certains compilateurs génèrent aussi du code assez grand (SBCL est un exemple).

  • y a-t-il des moyens de réduire la taille des applications? -> Cela dépend du système Lisp. Les systèmes Lisp commerciaux comme LispWorks et Allegro CL peuvent. Pour la livraison des applications, ils peuvent supprimer le code inutilisé, supprimer les informations de débogage, supprimer des parties du Lisp (bibliothèques, compilateur, ...) et plus encore. Les systèmes Common Lisp peuvent générer de petits exécutables. Je veux dire vraiment petit. -> Pas vraiment. Les exécutables sont soit grands (CCL) ou très grands (SBCL). Certains systèmes Common Lisp peuvent générer des exécutables de taille moyenne. Mais aucun ne peut vraiment générer de petits exécutables.

  • Y at-il vraiment aucun moyen de générer de très petits exécutables? -> Il y a des années, on a écrit des compilateurs qui génèrent du code C relativement compact sans grandes bibliothèques. Mais ces compilateurs ne sont pas conservés.

  • y a-t-il d'autres façons de réduire les exécutables? -> Si vous souhaitez exécuter plusieurs applications Lisp, il est logique de réutiliser les bibliothèques d'exécution et de compilation dans une ou plusieurs bibliothèques partagées. De cette façon, le code à livrer sera plus petit, lorsqu'une exécution est déjà installée en tant que bibliothèque partagée (ou similaire). Comment puis-je savoir ce que le Lisp que j'utilise prend en charge la livraison des applications? -> lisez le manuel et demandez aux autres utilisateurs.

  • ok, donc la plupart des systèmes Common Lisp ne peuvent pas générer de petites applications. Existe-t-il d'autres dialectes Lisp pouvant générer des exécutables plus petits. -> Oui, certains compilateurs Scheme peuvent.

  • Comment Common Lisp gère-t-il les erreurs d'exécution? -> dépend de la façon dont vous générez l'application. Par défaut, vous obtenez un débogueur Lisp (sauf si vous l'avez supprimé). Mais vous pouvez utiliser vos propres routines de gestion des erreurs dans votre application et empêcher l'apparition du débogueur.

  • Quelles sont les forces particulières Common Lisp, lors de la génération de petits exécutables n'est pas un? -> vous pouvez inclure un REPL pour interagir avec l'application, vous pouvez utiliser un compilateur inclus pour compiler nouveau (ou modifié le code) à l'exécution, vous pouvez utiliser le chargeur FASL (compilé Lisp code) pour CHARGER du code natif supplémentaire à l'exécution plugins, patches, extensions, ...), la gestion des erreurs sophistiquées y compris la récupération d'erreur est possible, ...

  • mais Lisp est dynamique? -> Oui, dynamique signifie qu'il peut changer beaucoup de choses pendant l'exécution. Par exemple, dans Common Lisp, vous pouvez modifier une classe CLOS au moment de l'exécution et les instances de la classe adopteront les modifications. Mais les différents systèmes Lisp ont différentes façons de supprimer certaines fonctionnalités dynamiques. Les structures sont moins dynamiques que les classes CLOS. Vous pouvez déclarer des types et les compiler avec différents paramètres d'optimisation (vitesse, sécurité, débogage, ...). Vous pouvez intégrer des fonctions. Et plus.

Un moyen simple de voir le code compilé pour les fonctions est d'utiliser la fonction Common Lisp DISASSEMBLE. Exemple dans Clozure CL sur un Mac x86-64

? (defun foo (x y) (if (= x y) (sin x) (* y (cos x)))) 
FOO 
? (disassemble 'foo) 
L0 
    [0]  (leaq (@ (:^ L0) (% rip)) (% fn)) 
    [7]  (cmpl ($ 16) (% nargs)) 
    [10] (jne L209) 
    [16] (pushq (% rbp)) 
    [17] (movq (% rsp) (% rbp)) 

...

[172] (pushq (@ 77752)) 
    [179] (jmpq (@ 10 (% temp0))) 
L189 
    [189] (leaq (@ (:^ L0) (% rip)) (% fn)) 
    [196] (jmpq (@ .SPNVALRET)) 
L209 
    [209] (uuo-error-wrong-number-of-args) 
NIL 

La sortie de DÉSASSEMBLER dépend évidemment de l'architecture du processeur, le système d'exploitation, le compilateur Lisp utilisé et les paramètres d'optimisation en cours .

+0

Et si quelque chose est changé pendant l'exécution, que se passe-t-il? Lisp génère-t-il une nouvelle version du code machine, ou les modifications affectent-elles seulement la «structure interne de la structure des données»? – Headcrab

+0

Dépend des changements. Certains peuvent ne pas avoir besoin d'un compilateur, d'autres peuvent utiliser le compilateur interne, d'autres n'utiliseront que du code nouvellement chargé (pour remplacer ou étendre le code existant), d'autres n'auront pas besoin d'un compilateur. Toutes les variantes sont possibles. –

4

Vous pariez. Chez Scheme (un compilateur commercial) est l'un des meilleurs. Gambit et Larceny sont des compilateurs de recherche qui génèrent aussi du code natif.

+0

http://www.iro.umontreal.ca/~gambit/ Gambit Page d'accueil http://www.ccs.neu.edu/home/will/Larceny/ Larceny Page d'accueil Gambit compile en C, Larceny compile soit pour C, le code machine ou le CLR. –

3

Oui. Voir http://en.wikipedia.org/wiki/Common_Lisp. Il mentionne que Steel Bank Common Lisp (une implémentation assez populaire) compile tout à natif par défaut. Le fait que les garbage collection et autres soient utilisés ne constitue pas un obstacle au code natif. Cela signifie simplement qu'une sorte d'exécution est nécessaire. Mais alors quoi? Même C a une durée d'exécution.

9

Il y a beaucoup de compilateurs Lisp qui compilent en code natif. CMUCL, SBCL, ClozureCL sont connus parmi les compilateurs Lisp open-source.

La récupération de place n'est pas un obstacle à la compilation en code natif. De plus, dans certains cas, Lisp peut utiliser une allocation de pile qui n'a pas besoin de GC et peut grandement améliorer les performances (en utilisant la déclaration dynamic-extent, au moins SBCL la prend en charge). Les macros (et tout code exécuté en lecture (lecture des macros et lecture-évaluation), à la compilation (macros, macros du compilateur, code dans eval-when)) nécessitent une compilation incrémentielle (la première macro-fonction a être compilé, puis le code qui utilise la macro peut être compilé). Cela complique un peu la compilation, mais ce n'est pas trop un problème. En outre, les macros et les macros de compilateurs aident même le processus de compilation car ils permettent au programmeur d'écrire des générateurs de code et des optimiseurs de code, en personnalisant essentiellement le compilateur. Le compilateur est donc plus compliqué que certains langages plus simples (comme C), mais la complexité est gérable (voir Design of CMU Common Lisp).

La nature dynamique de Common Lisp est contrôlable et conçue pour être compilable efficacement. Contrairement à d'autres langages dynamiques (par exemple, Python), le dynamisme est restreint (par exemple, vous ne pouvez pas prendre l'environnement lexical actuel à l'exécution) ce qui donne aux compilateurs une certaine liberté d'optimisation.

+0

J'avais essayé plusieurs compilateurs il y a quelques temps. Ce que j'ai pu faire avec eux était quelque chose comme ~ 10 Mo pour un "Hello, World!" Windows fichier .exe, qui vous montre une invite Lisp s'il y a une erreur d'exécution. Donc, il semble que tout le système Lisp a été traîné avec lui, ce qui vous fait penser que ce n'est pas vraiment "natif", peut-être ... – Headcrab

+10

Hmm, java fait glisser toute l'exécution de Java, .net traîne tout le clr, C++ traîne le Tout C++ rt, Lisp traîne toute l'exécution de Lisp. C'est juste la même chose - presque chaque langue nécessite son propre temps d'exécution. L'exécution de Lisp est importante en raison de sa flexibilité (il en va de même pour jvm et clr). Cependant, le code est toujours natif: c'est-à-dire que les instructions ne concernent pas la machine virtuelle mais la CPU cible. –

+0

Je pense que certaines lisps fournissent un moyen de jeter des images avec certaines fonctionnalités supprimées (comme le compilateur, si ce n'est pas utilisé). peut-être que cela pourrait aider à le rétrécir un peu? –

4

Ne pas oublier Chicken Schéma.

+0

Pourquoi les Downvotes? L'OP voulait aussi connaître le schéma, et le poulet est un compilateur natif. –