6
votes

Convertir une expression de schéma à une chaîne

donné une expression '(Lambda (x) x) Comment puis-je traduire cela en une chaîne. Je pensais que Symbole-> String fera le travail mais non, ce n'est pas un symbole.

E.g pour une macro to-string: (to-string (lambda (x) x)) Cela devrait renvoyer >> "(Lambda (x) x)"

Toutes les idées, merci


2 commentaires

Juste une clarification que je traite avec la liste citée. Je marcherais sur la liste et faire des cordes-concats, mais je ne sais pas comment faire face à Variamics E, G '(Lambda (X. Y) (Affichage X) (Affichage Y))


Quelle variante de schéma utilisez-vous? Est-ce compatible R6RS, ou seulement Compatible R5RS?


6 Réponses :


1
votes

Vous devriez parcourir les consoles. Lorsqu'un nouveau contre commence à écrire "(", quand il se termine écrire ")" et utilisez symbole-> chaîne pour les symboles à l'intérieur des consoles.

Vous pouvez l'étendre avec le type d'expédition. Peut-être assez d'impression existe aussi dans le schéma?


2 commentaires

Merci Trickster pour la réponse rapide. J'ai également pensé à cette solution, mais je ne sais alors pas comment traiter des cas de fonctions variadiques par exemple '(Lambda (x. Y) (+ x y)) Comment connaître réellement le. entre x et y et sortie "(lambda (x. y) (+ x y))"


Eh bien, (x y) est (contre x (contre y nil)) et (x. y) est (inconvénient x y)



1
votes

Utilisez Pretty-Format CODE> :

(pretty-format v [columns]) → string?


1 commentaires

Malheureusement, la mise en œuvre du schéma que j'utilise ne met pas en œuvre jolie format :( une autre alternative?



5
votes

L'expression '(lambda (x) x) est une liste citée.

L'expression (lambda (x) x) est une sorte de type de compilé, opaque, exécutable, objet interne du temps d'exécution.

symbole-> chaîne convertit simplement un symbole en chaîne, qui est une séquence de caractères.

Si vous travaillez avec une liste, vous pouvez simplement parcourir la liste et imprimer les composants individuels. En fait, (écrire '(lambda (x) x)) imprimera simplement la liste.

De nombreux schémas ont quelque chose d'apparentant à (avec-sortie-to-string ...) qui renvoie une chaîne de toutes les sorties écrites dans le port standard.

Cependant, si vous faites (écrire (lambda (x) x)) , vous obtiendrez qui sait quoi. Vous obtiendrez tout ce que la mise en œuvre fournit lors du déversement d'un type de fonction exécutable. Certains peuvent imprimer un "démontage" montrant le code source. D'autres peuvent simplement imprimer #fonction ou quelque chose de même inutile.

En bref, si vous voulez simplement imprimer une liste, il y a toutes sortes de mécanismes pour cela.

Si vous souhaitez imprimer le code source d'une fonction compilée, c'est un problème complètement différent, dépendant très de la mise en œuvre et peut être impossible.


0 commentaires

8
votes

schéma standard (au moins au sens R5RS) n'a aucun moyen de le faire, donc si vous voulez du code portable, vous devez marcher vous-même de marcher vous-même. Fastidieux, mais pas trop compliqué (même pour les listes pointillées). Mais si vous voulez juste une version de travail , vous devez rechercher dans le manuel de votre implémentation et rechercher le moyen de le faire. La réponse sera presque toujours simple, par exemple, dans le schéma PLT, vous utiliserez (format "~ s" '(Lambda ...))


2 commentaires

Cette réponse est correcte, bien que les implémentations prennent en charge SRFI 6, vous pouvez simplement créer un port de chaîne de sortie et écrire .


Le fait est que le faire directement peut dans certains cas être plus efficace. Si vous allez la route SRFI, SRFI-28 formalise le format . (Et oui, la mise en œuvre de la référence utilise SRFI-6, mais les implémentations utiliseront souvent tout ce que les cométioles qu'ils ont - la mise en œuvre de MZScheme de SRFI-26 utilise simplement son propre format .)



0
votes

Ceci est un code simple qui, je pense, fait ce que vous voulez.
Il n'utilise pas de choses spécifiques à la mise en œuvre et est tout à fait simple.

Notez cependant qu'il ne gère pas correctement les caractères spéciaux dans les chaînes (par exemple, "A \" B \ "C" se tournera vers "A" B "C"). P>

(define join
    (lambda (l delim to-str)
      (fold-left
        (lambda (str elem)
          (string-append str delim (to-str elem)))
        (to-str (car l))
        (cdr l))))
(define sexpr->string 
      (lambda (sexpr)
        (cond 
          ((number? sexpr) (number->string sexpr))
          ((symbol? sexpr) (symbol->string sexpr))
          ((boolean? sexpr) (if sexpr "#t" "#f"))
          ((string? sexpr) (string-append "\"" sexpr "\""))
          ((char? sexpr) (string-append "#\\" (string sexpr)))
          ((vector? sexpr) 
           (let ((s-vec (join (vector->list sexpr) " " sexpr->string)))
             (string-append "#(" s-vec ")")))
          ((null? sexpr) "()")
          ((list? sexpr) (string-append "(" (join sexpr " " sexpr->string) ")"))

          ((pair? sexpr) 
           (let ((s-car (sexpr->string (car sexpr)))
                 (s-cdr (sexpr->string (cdr sexpr))))
             (string-append "(" s-car " . " s-cdr ")"))))))


0 commentaires

0
votes

Si vous utilisez un schéma compatible R6RS, vous pouvez utiliser le écrire code> fonction associée à Port de sortie d'appel avec chaîne code> .

> (string->expr "(lambda (x) (+ x 1))")
(lambda (x) (+ x 1))
> (equal? (string->expr "(lambda (x) (+ x 1))")
          '(lambda (x) (+ x 1)))
#t
> (equal? (string->expr (expr->string '(lambda (x) (+ x 1))))
          '(lambda (x) (+ x 1)))
#t


0 commentaires