lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: parsing ly code from SCM


From: Nicolas Sceaux
Subject: Re: parsing ly code from SCM
Date: Sun, 25 Apr 2004 15:36:34 +0200
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Sun, 25 Apr 2004 12:37:13 +0200, Jan a dit : 

 > I've made another step (CVS), what do you think?

 > #(ly:export 'result)
 > #(module-define! (resolve-module '(scm toto)) 'result result)

oh, that's what I was desperately looking for!

We should use a symbol that is not likely to be already used.
The following function generate a symbol each time it is called:

/
| (define gen-lily-sym
|   ;; Generate a lilyvartmpXX symbol, that may be (hopefully) unique.
|   (let ((var-idx -1))
|     (lambda ()
|       (set! var-idx (1+ var-idx))
|       (string->symbol (format #f "lilyvartmp~a"
|                               (list->string (map (lambda (chr)
|                                                    (integer->char (+ 
(char->integer #\a) 
|                                                                      (- 
(char->integer chr)
|                                                                         
(char->integer #\0)))))
|                                                  (string->list 
(number->string var-idx)))))))))
\

Then, ly:parse-string-result may look like:

/
| (define-public (ly:parse-string-result str module)
|   "Parse `str', which is supposed to contain a music expression."
|   (let ((music-sym (gen-lily-sym)))
|     (ly:parser-parse-string
|      parser
|      (format #f "
| ~a = { ~a }
| #(ly:export '~a)
| #(module-define! (resolve-module '~a) '~a ~a)
| "
|              music-sym str music-sym (module-name module) music-sym 
music-sym))
|   (eval `,music-sym module)))
\

Maybe a single strange symbol is enough, and generating each time an
other symbol is useless, I don't know.

 > What would be the best way to integrate this into Lily (the toto module?)

Can not it be in the (lily) module? For instance:

;;;; ly-from-scheme.scm -- parsing LilyPond music expressions from scheme
;;;;
;;;;  source file of the GNU LilyPond music typesetter
;;;; 
;;;; (c)  2000--2004  Han-Wen Nienhuys <address@hidden>
;;;;                  Jan Nieuwenhuizen <address@hidden>


(define gen-lily-sym
  ;; Generate a lilyvartmpXX symbol, that may be (hopefully) unique.
  (let ((var-idx -1))
    (lambda ()
      (set! var-idx (1+ var-idx))
      (string->symbol (format #f "lilyvartmp~a"
                              (list->string (map (lambda (chr)
                                                   (integer->char (+ 
(char->integer #\a) (- (char->integer chr)
                                                                                
            (char->integer #\0)))))
                                                 (string->list (number->string 
var-idx)))))))))

(define-public (ly:parse-string-result str module)
  "Parse `str', which is supposed to contain a music expression."
  (let ((music-sym (gen-lily-sym)))
    (ly:parser-parse-string
     parser
     (format #f "
~a = { ~a }
#(ly:export '~a)
#(module-define! (resolve-module '~a) '~a ~a)
"
             music-sym str music-sym (module-name module) music-sym music-sym))
  (eval `,music-sym module)))

(define-public (read-lily-expression chr port)
  "Read a #{ lily music expression #} from port and return
the scheme music expression. The $ character may be used to introduce
scheme forms, typically symbols. $$ may be used to simply write a `$'
character."
  (let* ((format-args '())
         (lily-string (with-output-to-string
                        (lambda ()
                          (do ((c (read-char port) (read-char port)))
                              ((and (char=? c #\#)
                                    (char=? (peek-char port) #\}))
                               (read-char port))
                            (cond ((and (char=? c #\$)
                                        (not (char=? (peek-char port) #\$)))
                                   ;; a $variable
                                   (display "~a")
                                   (set! format-args (cons (read port) 
format-args)))
                                  ((and (char=? c #\$)
                                        (char=? (peek-char port) #\$))
                                   ;; just a $ character
                                   (display (read-char port)))
                                  (else
                                   ;; other caracters
                                   (display c))))))))
   `(ly:parse-string-result (format #f ,lily-string ,@(reverse! format-args))
                            (current-module))))

(read-hash-extend #\{ read-lily-expression)
Index: ChangeLog
===================================================================
RCS file: /cvsroot/lilypond/lilypond/ChangeLog,v
retrieving revision 1.2121
diff -u -r1.2121 ChangeLog
--- ChangeLog   25 Apr 2004 09:55:27 -0000      1.2121
+++ ChangeLog   25 Apr 2004 13:27:08 -0000
@@ -1,3 +1,11 @@
+2004-04-25  Nicolas Sceaux  <address@hidden>
+
+       * scm/lily.scm (ly:load): Add ly-from-scheme.scm loading.
+
+       * scm/ly-from-scheme.scm: New file. Introduce a new syntax:
+       #{ lily music expression #} that returns an equivalent scheme
+       music expression by parsing the string.
+
 2004-04-25  Jan Nieuwenhuizen  <address@hidden>
 
        * lily/my-lily-parser.cc:
Index: scm/lily.scm
===================================================================
RCS file: /cvsroot/lilypond/lilypond/scm/lily.scm,v
retrieving revision 1.236
diff -u -r1.236 lily.scm
--- scm/lily.scm        24 Apr 2004 21:48:02 -0000      1.236
+++ scm/lily.scm        25 Apr 2004 13:27:11 -0000
@@ -442,6 +442,8 @@
        "define-music-properties.scm"
        "auto-beam.scm"
        "chord-name.scm"
+
+       "ly-from-scheme.scm"
        
        "define-context-properties.scm"
        "translation-functions.scm"
#(define (textoffset dx dy)
  #{ \override Voice.TextScript #'extra-offset = #(cons $dx $dy) #})

#(define (export-lily-expression chr port)
  `(ly:export ,(read port)))

#(read-hash-extend #\x export-lily-expression)

\score {
    \notes {
        c'^"normal text"
        
        ##x(textoffset 3 -4)
        
        c'^"text with offset hm"
    }
}
nicolas

reply via email to

[Prev in Thread] Current Thread [Next in Thread]