nyacc: something working
authorMatt Wette <matt.wette@gmail.com>
Sat, 14 Jan 2017 23:16:28 +0000 (15:16 -0800)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 14 Jan 2017 23:16:28 +0000 (15:16 -0800)
module/nyacc/lang/c99/cppbody.scm

index 7f9aad7f40b9c1c79d30057fdafe62846ad06da5..6306216279128a0cc75cb640639d23ae87f9b7ad 100644 (file)
 ;; first character of new replacement text.
 ;; @end enumerate
 
-;; @deffn scan-cpp-input ch argd used dict end-tok => string
+;; @deffn scan-cpp-input argd used dict end-tok => string
 ;; Process replacement text from the input port and generate a (reversed)
 ;; token-list.  If end-tok, stop at, and push back, @code{,} or @code{)}.
+;; If end-tok is @code{,} then read until @code{,} or @code{(}.
 ;; The argument @var{argd} is a dictionary (argument name, argument
 ;; value) pairs which will be expanded as needed.  This routine is called
 ;; by collect-args, expand-cpp-repl and cpp-expand-text.
-(define (scan-cpp-input ch argd dict used end-tok)
-  (let ((res (x-scan-cpp-input ch argd dict used end-tok)))
+(define (scan-cpp-input argd dict used end-tok)
+  (let ((res (x-scan-cpp-input argd dict used end-tok)))
     (simple-format #t "scan=>~S\n" res)
     res))
-(define (x-scan-cpp-input ch argd dict used end-tok)
+(define (x-scan-cpp-input argd dict used end-tok)
   ;; Works like this: scan tokens (comments, parens, strings, char's, etc).
   ;; Tokens (i.e., strings) are collected in a (reverse ordered) list (stl)
   ;; and merged together on return.  Lone characters are collected in the
   ;; We just scanned "defined", now need to scan the arg to inhibit expansion.
   ;; For example, we have scanned "defined"; we now scan "(FOO)" or "FOO", and
   ;; return "defined(FOO)".  We use ec (end-char) as state indicator: nul at
-  ;; start, #\) on seeing #\( or #\space if other.
+  ;; start, #\) on seeing #\( or #\nul if other.
   (define (scan-defined-arg)
-    (let* ((ch (skip-ws ch)) (ec (if (char=? ch #\() #\) #\space)))
+    (let* ((ch (skip-ws ch)) (ec (if (char=? ch #\() #\) #\nul)))
       (let iter ((chl '(#\()) (ec ec) (ch ch))
        (cond
-        ((and (eof-object? ch) (char=? #\space ec))
+        ((and (eof-object? ch) (char=? #\nul ec))
          (string-append "defined" (list->string (reverse (cons #\) chl)))))
         ((eof-object? ch) (cpp-err "illegal argument to `defined'"))
         ((and (char=? ch #\)) (char=? ec #\)))
             (chl '())          ; char-list (current list of input chars)
             (nxt #f)           ; next string 
             (lvl 0)            ; level
-            (ch ch))   ; next character
+            (ch (read-char)))  ; next character
     (simple-format #t "iter ch=~S stl=~S chl=~S nxt=~S lvl=~S ch=~S\n"
                   ch stl chl nxt lvl ch)
     (cond
       (apply string-append (reverse (add-chl chl stl))))
      
      ((and (eqv? end-tok ch) (zero? lvl))
-      (unread-char ch)
-      (apply string-append (reverse (add-chl chl stl))))
+      (unread-char ch) (apply string-append (reverse (add-chl chl stl))))
      ((and end-tok (char=? #\) ch) (zero? lvl))
-      (unread-char ch)
-      (apply string-append (reverse (add-chl chl stl))))
+      (unread-char ch) (apply string-append (reverse (add-chl chl stl))))
      
      ((read-c-comm ch #f) =>
       (lambda (cp) (iter stl chl (string-append "/*" (cdr cp) "*/")
                (iter stl chl rval lvl (read-char)))
               ((pair? rval)            ; cpp macro
                (let* ((argl (car rval)) (text (cdr rval))
-                      (argd (collect-args (read-char) argl argd dict used))
+                      (argd (collect-args argl argd dict used))
                       (newl (expand-cpp-repl text argd dict (cons iden used))))
                  (iter stl chl newl lvl (read-char))))
               (else                    ; normal identifier
      (else
       (iter stl (cons ch chl) #f lvl (read-char))))))
 
-;; @deffn collect-args ch argl argd dict used => argd
+;; @deffn collect-args argl argd dict used => argd
 ;; to be documented
 ;; I think argd is a passthrough for scan-cpp-input
 ;; argl: list of formal arguments in #define
 ;; used: list of already expanded macros
 ;; TODO clean this up
 ;; should be looking at #\( and eat up to matching #\)
-(define (collect-args ch argl argd dict used)
+(define (collect-args argl argd dict used)
   (simple-format #t "collect-args: argl=~S argd=~S dict=~S\n" argl argd dict)
-  (if (not (eqv? (skip-ws ch) #\()) (cpp-err "CPP expecting `('"))
-  (let iter ((argl argl) (argv '()) (ch (read-char)))
+  (let iter ((argl argl) (argv '()) (ch (skip-ws (read-char))))
+    ;; ch should always be #\(, #\, or #\)
     (simple-format #t "  ch=~S\n" ch)
     (cond
      ((eqv? ch #\)) (reverse argv))
-     ((null? argl)
-      (if (eqv? ch #\space) (iter argl argv ch) (cpp-err "arg count")))
+     ((null? argl) (cpp-err "arg count"))
      ((and (null? (cdr argl)) (string=? (car argl) "..."))
+      ;; depending on scan-cpp-input being called before read-char
       (iter (cdr argl)
-           (acons "__VA_ARGS__" (scan-cpp-input ch argd dict used #\)) argv)
+           (acons "__VA_ARGS__" (scan-cpp-input argd dict used #\)) argv)
            (read-char)))
-     (else
+     ((or (eqv? ch #\() (eqv? ch #\,))
+      ;; depending on scan-cpp-input being called before read-char
       (iter (cdr argl)
-           (acons (car argl) (scan-cpp-input ch argd dict used #\,) argv)
-           (read-char))))))
+           (acons (car argl) (scan-cpp-input argd dict used #\,) argv)
+           (read-char)))
+     (else (error "coding error, ch=" ch)))))
 
 ;; @deffn expand-cpp-repl
 ;; to be documented
 (define (expand-cpp-repl repl argd dict used)
   (with-input-from-string repl
-    (lambda () (scan-cpp-input (read-char) argd dict used #f))))
+    (lambda () (scan-cpp-input argd dict used #f))))
 
 ;; @deffn cpp-expand-text text dict => string
 (define (cpp-expand-text text dict)
   (with-input-from-string text
-    (lambda () (scan-cpp-input (read-char) '() dict '() #f))))
+    (lambda () (scan-cpp-input '() dict '() #f))))
 
 ;; @deffn expand-cpp-mref ident dict => repl|#f
 ;; Given an identifier seen in C99 input, this checks for associated
        (simple-format #t "expand-cpp-mref: ch=~S\n" ch)
        (unread-char ch))
       (let* ((argl (car rval)) (repl (cdr rval))
-            (argd (collect-args (read-char) argl '() dict '()))
+            (argd (collect-args argl '() dict '()))
             (expd (expand-cpp-repl repl argd dict (cons ident used))))
        expd)))))