]> git.donarmstrong.com Git - lilypond.git/blobdiff - scm/ly-from-scheme.scm
Fix compile bug, add linewidth info to \justify.
[lilypond.git] / scm / ly-from-scheme.scm
index 0436f423e8fece61e9ed175a6a78cbfa92607421..79267499bd2a5a184af4ca7af4b89f56974a685e 100644 (file)
@@ -2,9 +2,8 @@
 ;;;;
 ;;;;  source file of the GNU LilyPond music typesetter
 ;;;; 
-;;;; (c)  2000--2004  Han-Wen Nienhuys <hanwen@cs.uu.nl>
-;;;;                  Jan Nieuwenhuizen <janneke@gnu.org>
-
+;;;; (c) 2004--2005  Nicolas Sceaux  <nicolas.sceaux@free.fr>
+;;;;           Jan Nieuwenhuizen <janneke@gnu.org>
 
 (define gen-lily-sym
   ;; Generate a lilyvartmpXX symbol, that may be (hopefully) unique.
                                                                                             (char->integer #\0)))))
                                                  (string->list (number->string var-idx)))))))))
 
-(define-public (ly:parse-string-result str module)
+(define-public (ly:parse-string-result str parser)
   "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)))
+     (format #f "parseStringResult = { ~a }" str))
+
+    (ly:parser-lookup parser 'parseStringResult)))
 
 (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 ()
+  (let ((bindings '()))
+
+    (define (create-binding! val)
+      "Create a new symbol, bind it to `val' and return it."
+      (let ((tmp-symbol (gen-lily-sym)))
+
+        (set! bindings (cons (cons tmp-symbol val) bindings))
+        tmp-symbol))
+    
+    (define (remove-dollars! form)
+      "Generate a form where `$variable' and `$ value' mottos are replaced
+      by new symbols, which are binded to the adequate values."
+      (cond (;; $variable
+             (and (symbol? form)
+                  (string=? (substring (symbol->string form) 0 1) "$")
+                  (not (and (<= 2 (string-length (symbol->string form)))
+                           (string=? (substring (symbol->string form) 1 2) "$"))))
+             (create-binding! (string->symbol (substring (symbol->string form) 1))))
+            (;; atom
+             (not (pair? form)) form)
+            (;; ($ value ...)
+             (eqv? (car form) '$)
+             (cons (create-binding! (cadr form)) (remove-dollars! (cddr form))))
+            (else ;; (something ...)
+             (cons (remove-dollars! (car form)) (remove-dollars! (cdr form))))))
+    (let*
+       ((lily-string (call-with-output-string
+                        (lambda (out)
                           (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))))
+                             ((and (char=? c #\#)
+                                   (char=? (peek-char port) #\})) ;; we stop when #} is encoutered
+                              (read-char port))
+                           (cond
+                            ;; a $form expression
+                            ((and (char=? c #\$) (not (char=? (peek-char port) #\$)))
+                             (format out "\\~a" (create-binding! (read port))))
+                            ;; just a $ character
+                            ((and (char=? c #\$) (char=? (peek-char port) #\$))
+                            ;; pop the second $
+                             (display (read-char port) out))
+                            ;; a #scheme expression
+                            ((char=? c #\#)
+                             (let ((expr (read port)))
+                               (format out "#~s" (if (eq? '$ expr)
+                                                     (create-binding! (read port))
+                                                     (remove-dollars! expr)))))
+                            ;; other caracters
+                            (else
+                             (display c out)))))))
+
+         (result
+          `(let ((parser-clone (ly:clone-parser parser)))
+             ,@(map (lambda (binding)
+                      `(ly:parser-define! parser-clone ',(car binding) ,(cdr binding)))
+                    (reverse bindings))
+             (ly:parse-string-result ,lily-string parser-clone))
+         ))
+
+      
+            
+      result
+      )))
 
 (read-hash-extend #\{ read-lily-expression)