Some fixes #31
@@ -135,9 +135,6 @@ forms, and what remains."
|
|||||||
(car type)
|
(car type)
|
||||||
type))
|
type))
|
||||||
|
|
||||||
(define (comment-form? f)
|
|
||||||
(and (pair? f) (eq? (car f) 'comment)))
|
|
||||||
|
|
||||||
;;; Strip ;s so ;;; Foo becomes /* Foo */ and not /* ;; Foo */
|
;;; Strip ;s so ;;; Foo becomes /* Foo */ and not /* ;; Foo */
|
||||||
(define (strip-comment-marker text)
|
(define (strip-comment-marker text)
|
||||||
(string-trim-both (string-trim text #\;)))
|
(string-trim-both (string-trim text #\;)))
|
||||||
|
|||||||
38
reader.scm
38
reader.scm
@@ -115,6 +115,21 @@
|
|||||||
((eq? tok dot-token) (error "Unexpected ."))
|
((eq? tok dot-token) (error "Unexpected ."))
|
||||||
(else tok))))
|
(else tok))))
|
||||||
|
|
||||||
|
;;; A token that stands for a datum
|
||||||
|
(define (datum-token? tok)
|
||||||
|
(not (or (eof-object? tok)
|
||||||
|
(eq? tok close-paren)
|
||||||
|
(eq? tok close-bracket)
|
||||||
|
(eq? tok dot-token))))
|
||||||
|
|
||||||
|
;;; next-token, sans the comments
|
||||||
|
(define (next-code-token port)
|
||||||
|
(let loop ()
|
||||||
|
(let ((tok (next-token port)))
|
||||||
|
(if (comment-form? tok)
|
||||||
|
(loop)
|
||||||
|
tok))))
|
||||||
|
|
||||||
;;; Read list elements up to close-paren or close-bracket,
|
;;; Read list elements up to close-paren or close-bracket,
|
||||||
;;; honoring dotted-pair notation (a b . c)
|
;;; honoring dotted-pair notation (a b . c)
|
||||||
(define (read-list port closer)
|
(define (read-list port closer)
|
||||||
@@ -208,13 +223,24 @@
|
|||||||
(else (error "Malformed feature expression" test))))
|
(else (error "Malformed feature expression" test))))
|
||||||
|
|
||||||
;;; The #-/#+ preceded datum is always read -- there is no other way
|
;;; The #-/#+ preceded datum is always read -- there is no other way
|
||||||
;;; to know where it ends -- and then either returned or dropped
|
;;; to know where it ends -- and then either returned or dropped. What
|
||||||
|
;;; follows a dropped datum is read in its place: `#+x #+y (a) (b)'
|
||||||
|
;;; with only x is (b).
|
||||||
|
;;;
|
||||||
|
;;; That next thing may be nothing: the end of the file, or the
|
||||||
|
;;; paren closing the list we are in
|
||||||
(define (read-conditional port keep-when)
|
(define (read-conditional port keep-when)
|
||||||
(let ((keep (eq? keep-when (feature-true? (read-datum port)))))
|
(let* ((test (next-code-token port))
|
||||||
(if keep
|
(keep (begin
|
||||||
(read-datum port)
|
(unless (datum-token? test)
|
||||||
(begin (read-datum port)
|
(error "Unexpected end of input in feature expression"))
|
||||||
(next-token port)))))
|
(eq? keep-when (feature-true? test))))
|
||||||
|
(guarded (next-code-token port)))
|
||||||
|
(cond
|
||||||
|
(keep guarded)
|
||||||
|
;; A datum was dropped, so the next one stands in for it
|
||||||
|
((datum-token? guarded) (next-token port))
|
||||||
|
(else guarded))))
|
||||||
|
|
||||||
;;; #t / #true / #f / #false. `val' is the boolean; consume any
|
;;; #t / #true / #f / #false. `val' is the boolean; consume any
|
||||||
;;; trailing name characters and validate
|
;;; trailing name characters and validate
|
||||||
|
|||||||
@@ -145,9 +145,6 @@
|
|||||||
;;; C code it will be placed as a C commentary just before the function
|
;;; C code it will be placed as a C commentary just before the function
|
||||||
;;; definition (actually that works for all blocky things: enum, struct, union as well).
|
;;; definition (actually that works for all blocky things: enum, struct, union as well).
|
||||||
|
|
||||||
(define (comment-form? f)
|
|
||||||
(and (pair? f) (eq? (car f) 'comment)))
|
|
||||||
|
|
||||||
(define (fn-header-length fn-form)
|
(define (fn-header-length fn-form)
|
||||||
(if (memq (first fn-form) '(pub extern)) 5 4))
|
(if (memq (first fn-form) '(pub extern)) 5 4))
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,22 @@
|
|||||||
;; guards nest
|
;; guards nest
|
||||||
(feature-test '((a)) (x y) "#+x #+y (a)")
|
(feature-test '((a)) (x y) "#+x #+y (a)")
|
||||||
(feature-test '((b)) (x) "#+x #+y (a) (b)")
|
(feature-test '((b)) (x) "#+x #+y (a) (b)")
|
||||||
|
;; ...and the inner one may leave nothing behind: the end of the
|
||||||
|
;; file, or the paren closing the list, is what the outer one then
|
||||||
|
;; produces, and neither is an error
|
||||||
|
(feature-test '() (x) "#+x #+y (a)")
|
||||||
|
(feature-test '((f)) (x) "(f #+x #+y 1)")
|
||||||
|
(feature-test '((f 2)) (x) "(f #+x #+y 1 2)")
|
||||||
|
(feature-test '((a)) (x) "(a) #+x #+y (b)")
|
||||||
|
|
||||||
|
;; a comment between a guard and the form it guards describes the
|
||||||
|
;; guard. Taking it for the guarded datum would leave the form itself
|
||||||
|
;; unconditional
|
||||||
|
(feature-test '((a)) (x) "#+x ;; why\n (a)")
|
||||||
|
(feature-test '() (y) "#+x ;; why\n (a)")
|
||||||
|
(feature-test '((b)) (y) "#+x ;; why\n (a) (b)")
|
||||||
|
;; a comment after the guarded form is an ordinary form, and stays
|
||||||
|
(feature-test '((comment "; tail")) (y) "#+x (a) ;; tail")
|
||||||
|
|
||||||
;; a feature the program was not given is simply absent
|
;; a feature the program was not given is simply absent
|
||||||
(feature-test '() () "#+anything (a)")
|
(feature-test '() () "#+anything (a)")
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
(get-env-var
|
(get-env-var
|
||||||
set-working-directory
|
set-working-directory
|
||||||
to-absolute-pathname
|
to-absolute-pathname
|
||||||
|
comment-form?
|
||||||
list-split
|
list-split
|
||||||
list-join
|
list-join
|
||||||
recons
|
recons
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
(get-env-var
|
(get-env-var
|
||||||
set-working-directory
|
set-working-directory
|
||||||
to-absolute-pathname
|
to-absolute-pathname
|
||||||
|
comment-form?
|
||||||
list-split
|
list-split
|
||||||
list-join
|
list-join
|
||||||
recons
|
recons
|
||||||
|
|||||||
@@ -42,6 +42,9 @@
|
|||||||
(current-directory)
|
(current-directory)
|
||||||
pathname)))
|
pathname)))
|
||||||
|
|
||||||
|
(define (comment-form? form)
|
||||||
|
(and (pair? form) (eq? (car form) 'comment)))
|
||||||
|
|
||||||
(define (list-split src-list split-elt)
|
(define (list-split src-list split-elt)
|
||||||
;; split '(1 2 / 3 4 / 5 6) by '/ -> '((1 2) (3 4) (5 6))
|
;; split '(1 2 / 3 4 / 5 6) by '/ -> '((1 2) (3 4) (5 6))
|
||||||
(fold (lambda (elt acc)
|
(fold (lambda (elt acc)
|
||||||
|
|||||||
Reference in New Issue
Block a user