Je travaille sur une langue de jouets qui compile sur C ++ sur la base de LISP (très petit sous-ensemble de schéma), j'essaie de déterminer comment représenter Let expression, au début Je pensais exécuter tous les exprs puis renvoyer le dernier mais le retour va tuer ma capacité à nicher des expressions, quelle serait la voie à suivre pour représenter la lettre? P> En outre, toute ressource sur la source de la transformation de la source à la source est évaluée. , J'ai googlé mais tout ce que je pouvais fier, c'est le compilateur de schéma de 90 min. P> p>
3 Réponses :
Si vous recherchez des outils pour vous aider à la traduction source à source, je recommanderais antlr . C'est très excellent. P>
Toutefois, vous devrez réfléchir à la façon de traduire d'une langue de typée (LISP) à une langue (C) sans loosité (C). Par exemple, dans votre question, quel est le type de 10 code>? Un court code>? Un int code>? Un double code>? P>
J'ai mon propre système d'objet 10 est un int sur le côté C ++, je sais ce que c'est pendant le temps d'exécution
Un moyen d'étendre puis, transformez ceci en une fonction et un Call correspondant en C ++: p> donc dans un contexte plus important: p> devient p> Il y a beaucoup plus de détails, tels que besoin d'accéder à des variables lexicales en dehors du laisser code> est de le traiter comme un lambda code>: let code> dans le laisser code>. Étant donné que C ++ n'a pas de fonctions lexiquement imbriquées (contrairement à Pascal, par exemple), cela nécessitera une mise en œuvre supplémentaire. P> P>
Je vais essayer d'expliquer une approche naïve de la compilation imbriquée
Compiler des fonctions Lisp ou Scheme directement dans les fonctions C ou C ++
sera délicat en raison des problèmes d'autres affiches soulevées. Cela dépend de
l'approche, le C ou C ++ résultant ne sera pas reconnaissable (ni même
très lisible). p> J'ai écrit un compilateur LISP-TO-C après la finition de la structure et de l'interprétation des programmes informatiques (c'est l'un des derniers exercices, et j'ai triché et vient d'écrire un traducteur du code d'octets SICP à C). Le sous-ensemble de C qu'elle émise n'a pas utilisé de fonctions C pour gérer les fonctions LISP du tout. C'est parce que le
Enregistrer la langue de la machine au chapitre 5 de la SICP est vraiment inférieur
que c. p> supposant que vous avez une forme d'environnement, qui lient les noms à des valeurs, vous pouvez définir le creux de fonction appelant comme ceci: étendre l'environnement que la fonction a été définie avec les paramètres formels liés aux arguments, puis évaluez le corps de la fonction dans ce nouvel environnement. P> Dans le compilateur de SICP, l'environnement est détenu dans une variable globale et il y a d'autres
Variables globales tenant la liste des arguments pour un appel de la fonction, comme
ainsi que l'objet de procédure appelé (l'objet de procédure inclut un pointeur à l'environnement dans lequel il a été défini) et une étiquette pour sauter lorsqu'une fonction retourne. P> Gardez à l'esprit que lorsque vous compilent une expression Lorsqu'une fonction est compilée, le code émis ressemble à quelque chose comme
ce pseudocode: p> ... où alors, lorsque le code compilé est exécuté, et il y a un appel à cette
Ceci est un peu difficile à expliquer, et je suis sûr que j'ai fait un embrouillé
travail de celui-ci. Je ne peux pas penser à un exemple décent qui ne me concerne pas fondamentalement de décrire le chapitre 5 du SICP. Puisque j'ai passé le temps d'écrire cette réponse, je vais le poster, mais je suis vraiment désolé s'il est désespérément déroutant. P> Je recommande fortement SICP couvre une interprétation métacolirculeuse pour les débutants, ainsi qu'un certain nombre de variantes sur l'interprète et un compilateur de code d'octet que j'ai réussi à obscurcir et caprice ci-dessus. Ce n'est que les deux derniers chapitres, les 3 premiers chapitres sont tout aussi bons. C'est un livre merveilleux. Absolument lu si vous ne l'avez pas encore fait. P> LISP comprend un certain nombre d'interprètes écrits dans un schéma, un compilateur au code octet et un compilateur à C. Je suis au milieu de cela et peut dire avec Confidence C'est un livre profond et riche valant bien le temps de toute personne intéressée par la mise en œuvre du LISP. Cela peut être un peu daté de ce point, mais pour un débutant comme moi, il est toujours précieux. Il est plus avancé que SICP, alors méfiez-vous. Il incombe à un chapitre au milieu sur la sémantique dénotationnationnose qui allait fondamentalement sur ma tête. P> Quelques autres notes: p> Compilateur auto-hébergement auto-hébergement de Darius Bacon P> Lambda Soulever , qui est une technique plus avancée que je pense que Marc Pertey utilise P> P> Lambda code> s. Depuis l'explication de Greg d'expansion laisse code> dans un lambda code>
est très bon, je ne traiterai pas laisser code> du tout, je suppose que laisser code> est
une forme ou une macro dérivée et est étendue dans un lambda code> formulaire qui est
Appelé immédiatement. lambda code>
sont deux composants syntaxiques que vous connaissez à la compilation: le formel
paramètres et le corps du lambda code>. p> * env * code> et * argl * code> sont les variables globales tenant le
Liste de l'environnement et des arguments, et EXTENDY code> est une fonction (ceci peut
être une fonction C ++ appropriée) qui étend l'environnement * env * code> par
jumelage des noms dans * argl * code> avec des valeurs dans [formals] code>. p> lambda code> ailleurs dans votre code, la convention appelante doit mettre
Le résultat de l'évaluation de la liste d'arguments dans la variable * argl * code>, mettez l'étiquette de retour dans la variable * Continuer * code>, puis passez à une étiquette /code >. lambda code> s, le code émis semblerait quelque chose
comme ceci: p>
+1 Pour souligner que c'est beaucoup plus compliqué que de traduire laisser code> à lambda code> / application
Voici un article de blog qui pourrait aider, ce blogueur a écrit un groupe d'articles sur le sujet de la compilation et celui-ci est lié aux fermetures de traitement. C'était juste affiché à Hn et m'a fait réfléchir à cette question: Matt.might.net/ Articles / Conversion de fermeture C'est une technique plus avancée que la naïve que j'ai décrite mais c'est écrit assez clairement.