nyacc: CPP working better now
authorMatt Wette <matt.wette@gmail.com>
Sun, 15 Jan 2017 16:47:49 +0000 (08:47 -0800)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 15 Jan 2017 16:47:49 +0000 (08:47 -0800)
module/nyacc/lang/c99/body.scm
module/nyacc/lang/c99/cpp.scm
module/nyacc/lang/c99/cppbody.scm

index 621cc3db8c42a32955b78d1aeb7b7973c825dc94..462fb82fae707887df9bf19e8e7b9f1775b78928 100644 (file)
                      (exp (parse-cpp-expr rhs)))
                 (eval-cpp-expr exp defs)))
             (lambda (key fmt . args)
-              (display "body.323\n")
               (report-error fmt args)
               (throw 'c99-error "CPP error"))))
            
                 (set! ppxs (cons 'skip1-pop (cdr ppxs))))
                (else (cpi-pop))))
              ((error)
-              (if (exec-cpp-stmts?) (report-error "CPP error: ~S" (cdr stmt))))
+              (if (exec-cpp-stmts?)
+                  (report-error "error: #error ~A" (cdr stmt))))
              ((pragma)
               ;; standard says implementation-defined if line is expanded
               #t)
              (else (cons 'cpp-stmt stmt))))
          
          (define (eval-cpp-line line)
-           (simple-format #t "line=~S\n" line)
            (with-throw-handler
             'cpp-error
             (lambda () (eval-cpp-stmt (read-cpp-stmt line)))
                     ((and (x-def? name mode)
                           (expand-cpp-mref name (cpi-defs info)))
                      => (lambda (st)
-                          (simple-format #t "st=~S\n" st)
                           (push-input (open-input-string st))
                           (iter (read-char))))
                     ((assq-ref keytab symb)
          ;; Loop between reading tokens and skipping tokens via CPP logic.
          (let iter ((pair (read-token)))
            (case (car ppxs)
-             ((keep)
-              ;;(simple-format #t "lx=>~S\n" pair)
-              pair)
+             ((keep) pair)
              ((skip-done skip-look)
               (iter (read-token)))
              ((skip1-pop)
index 927835d4918451b24d8529c87723c8cd5aad7e37..33fcd5082ad124ac5a7f6083a62423ef9ee73092 100644 (file)
@@ -61,26 +61,27 @@ todo:
   (letrec
       ((p-cppd ;; parse all
        (lambda ()
-         (let* ((iden (read-c-ident (skip-ws (read-char))))
-                ;;(args (or (p-args (skip-ws (read-char))) '()))
+         (let* ((iden (read-c-ident (skip-il-ws (read-char))))
                 ;; "define ABC(ARG)" not the same as "define ABC (ARG)"
                 (args (or (p-args (read-char)) '()))
-                (rest (or (p-rest (skip-ws (read-char))) " ")))
+                (rest (or (p-rest (skip-il-ws (read-char))) " ")))
            (if (pair? args)
                `(define (name ,iden) ,(cons 'args args) (repl ,rest))
                `(define (name ,iden) (repl ,rest))))))
        (p-args ;; parse args
        (lambda (la) ;; unread la if no match :(
          (if (eq? la #\()
-             (let iter ((args '()) (la (skip-ws (read-char))))
+             (let iter ((args '()) (la (skip-il-ws (read-char))))
                (cond
                 ((eq? la #\)) (reverse args))
                 ((read-c-ident la) =>
-                 (lambda (arg) (iter (cons arg args) (skip-ws (read-char)))))
+                 (lambda (arg)
+                   (iter (cons arg args) (skip-il-ws (read-char)))))
                 ((read-ellipsis la) =>
-                 (lambda (arg) (iter (cons arg args) (skip-ws (read-char)))))
+                 (lambda (arg)
+                   (iter (cons arg args) (skip-il-ws (read-char)))))
                 ((eq? la #\,)
-                 (iter args (skip-ws (read-char))))))
+                 (iter args (skip-il-ws (read-char))))))
              (begin (if (char? la) (unread-char la)) #f)))) ;; CLEANUP
        (p-rest ;; parse rest
        (lambda (la)
@@ -91,7 +92,7 @@ todo:
 ;; @deffn cpp-include
 ;; Parse CPP include statement.
 (define (cpp-include)
-  (let* ((beg-ch (skip-ws (read-char)))
+  (let* ((beg-ch (skip-il-ws (read-char)))
         (end-ch (if (eq? beg-ch #\<) #\> #\"))
         (path (let iter ((cl (list beg-ch)) (ch (read-char)))
                 (if (eq? ch end-ch) (list->string (reverse (cons ch cl)))
@@ -108,14 +109,14 @@ todo:
 ;; To evaluate the @code{if} statements use @code{parse-cpp-expr} and
 ;; @code{eval-cpp-expr}.
 (define (read-cpp-stmt line)
-  (define (rd-ident) (read-c-ident (skip-ws (read-char))))
-  (define (rd-num) (and=> (read-c-num (skip-ws (read-char))) cdr))
-  (define (rd-rest) (let ((ch (skip-ws (read-char))))
+  (define (rd-ident) (read-c-ident (skip-il-ws (read-char))))
+  (define (rd-num) (and=> (read-c-num (skip-il-ws (read-char))) cdr))
+  (define (rd-rest) (let ((ch (skip-il-ws (read-char))))
                      (if (not (eof-object? ch)) (unread-char ch))
                      (drain-input (current-input-port))))
   (with-input-from-string line
     (lambda ()
-      (let ((cmd (string->symbol (read-c-ident (skip-ws (read-char))))))
+      (let ((cmd (string->symbol (read-c-ident (skip-il-ws (read-char))))))
         (case cmd
           ((include) (cpp-include))
           ((define) (cpp-define))
index 6306216279128a0cc75cb640639d23ae87f9b7ad..1b8def58f2b5ceacd213cd9674f625e6e3830395 100644 (file)
 (define (cpp-err fmt . args)
   (apply throw 'cpp-error fmt args))
 
-;;.@deffn skip-ws ch
-(define (skip-ws ch)
-  (if (eof-object? ch) ch
-      (if (char-set-contains? c:ws ch)
-         (skip-ws (read-char))
-         ch)))
+;;.@deffn skip-il-ws ch
+;; Skip in-line whitespace
+(define skip-il-ws
+  (let ((il-ws (list->char-set '(#\space #\tab))))
+    (lambda (ch)
+      (cond
+       ((eof-object? ch) ch)
+       ((char-set-contains? il-ws ch) (skip-il-ws (read-char)))
+       (else ch)))))
 
 ;; Since we want to be able to get CPP statements with comment in tact
 ;; (e.g., for passing to @code{pretty-print-c99}) we need to remove
 ;; 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 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 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 #\nul if other.
+  ;; return "defined(FOO)".  We use ec (end-char) as terminal char:
+  ;; #\) if starts with #( or #\nul if other.
   (define (scan-defined-arg)
-    (let* ((ch (skip-ws ch)) (ec (if (char=? ch #\() #\) #\nul)))
-      (let iter ((chl '(#\()) (ec ec) (ch ch))
+    (let* ((ch (skip-il-ws (read-char)))
+          (ec (if (char=? ch #\() #\) #\null)))
+      (let iter ((chl '(#\()) (ec ec) (ch (if (char=? ec #\)) (read-char) ch)))
        (cond
-        ((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 #\)))
-         (string-append "defined" (list->string (reverse (cons ch chl)))))
+        ((eof-object? ch)
+         (if (char=? ec #\null)
+             (string-append "defined" (list->string (reverse (cons #\) chl))))
+             (cpp-err "illegal argument to `defined'")))
         ((char-set-contains? c:ir ch)
          (iter (cons ch chl) ec (read-char)))
-        (else (cpp-err "illegal identifier"))))))
+        ((char=? ec #\))
+         (if (char=? #\) (skip-il-ws ch))
+             (string-append "defined" (list->string (reverse (cons #\) chl))))
+             (cpp-err "garbage in argument to `defined'")))
+        ((char=? ec #\null) ;; past identifier
+         (string-append "defined" (list->string (reverse (cons #\) chl)))))
+        (else
+         (cpp-err "illegal argument to  `defined'"))))))
 
   (let iter ((stl '())         ; string list (i.e., tokens)
             (chl '())          ; char-list (current list of input chars)
             (nxt #f)           ; next string 
             (lvl 0)            ; level
             (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
      ;; have item to add, but first add in char's
      (nxt (iter (cons nxt (add-chl chl stl)) '() #f lvl ch))
       (lambda (st) (iter stl chl st lvl (read-char))))
      ((read-c-ident ch) =>
       (lambda (iden)
-       ;;(simple-format #t "  read-c-ident => ~S\n" iden)
        (if (equal? iden "defined")
            ;; "defined" is a special case
-           (iter stl chl (scan-defined-arg) lvl (read-char))
+           (let ((arg (scan-defined-arg)))
+             (iter stl chl arg lvl (read-char)))
            ;; otherwise ...
            (let* ((aval (assoc-ref argd iden))  ; lookup argument
                   (rval (assoc-ref dict iden))) ; lookup macro def
-             ;;(simple-format #t "    aval=~S rval=~S\n" aval rval)
              (cond
               ((and (pair? stl) (string=? "#" (car stl)))
-               ;;(simple-format #t "TEST iden=~S aval=~S\n" iden aval)
                (iter (cdr stl) chl (stringify aval) lvl (read-char)))
               ((and (pair? stl) (string=? "##" (car stl)))
-               ;;(simple-format #t "TEST iden=~S aval=~S\n" iden aval)
                (iter (cddr stl) chl (conjoin (cadr stl) aval) lvl (read-char)))
               ((member iden used)      ; name used
                (iter stl chl iden lvl (read-char)))
                       (newl (expand-cpp-repl text argd dict (cons iden used))))
                  (iter stl chl newl lvl (read-char))))
               (else                    ; normal identifier
-               ;;(simple-format #t "normal id stl=~S\n" stl)
                (iter stl chl iden lvl (read-char))))))))
      (else
       (iter stl (cons ch chl) #f lvl (read-char))))))
 ;; TODO clean this up
 ;; should be looking at #\( and eat up to matching #\)
 (define (collect-args argl argd dict used)
-  (simple-format #t "collect-args: argl=~S argd=~S dict=~S\n" argl argd dict)
-  (let iter ((argl argl) (argv '()) (ch (skip-ws (read-char))))
+  (let iter ((argl argl) (argv '()) (ch (skip-il-ws (read-char))))
     ;; ch should always be #\(, #\, or #\)
-    (simple-format #t "  ch=~S\n" ch)
     (cond
      ((eqv? ch #\)) (reverse argv))
      ((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 argd dict used #\)) argv)
-           (read-char)))
+      (let ((val (scan-cpp-input argd dict used #\))))
+       (iter (cdr argl) (acons "__VA_ARGS__" val argv) (read-char))))
      ((or (eqv? ch #\() (eqv? ch #\,))
-      ;; depending on scan-cpp-input being called before read-char
-      (iter (cdr argl)
-           (acons (car argl) (scan-cpp-input argd dict used #\,) argv)
-           (read-char)))
+      (let ((val (scan-cpp-input argd dict used #\,)))
+       (iter (cdr argl) (acons (car argl) val argv) (read-char))))
      (else (error "coding error, ch=" ch)))))
 
 ;; @deffn expand-cpp-repl
       (let ((expd (expand-cpp-repl rval '() dict (cons ident used))))
        expd))
      ((pair? rval)
-      (let ((ch (read-char)))
-       (simple-format #t "expand-cpp-mref: ch=~S\n" ch)
-       (unread-char ch))
       (let* ((argl (car rval)) (repl (cdr rval))
             (argd (collect-args argl '() dict '()))
             (expd (expand-cpp-repl repl argd dict (cons ident used))))