look past comments in a public form's header
This commit is contained in:
19
semen.scm
19
semen.scm
@@ -204,21 +204,10 @@
|
||||
acc)))
|
||||
|
||||
(define (strip-fn-header-comments fn-form)
|
||||
;; Remove comment forms from the function header
|
||||
;; ([pub|extern] fn name arglist rettype) so the positional accessors
|
||||
;; below are not shifted. Comments in the body are left in place as
|
||||
;; ordinary statements and preserved into the generated C.
|
||||
(let ((header-count (fn-header-length fn-form)))
|
||||
;; This always rebuilds the list, so the location has to be carried
|
||||
;; over explicitly -- otherwise every function loses it
|
||||
(copy-form-source!
|
||||
fn-form
|
||||
(let loop ((form fn-form) (kept 0) (acc (list)))
|
||||
(cond
|
||||
((null? form) (reverse acc))
|
||||
((= kept header-count) (append (reverse acc) form))
|
||||
((comment-form? (car form)) (loop (cdr form) kept acc))
|
||||
(else (loop (cdr form) (+ kept 1) (cons (car form) acc))))))))
|
||||
;; ([pub|extern] fn name arglist rettype). Comments in the body are
|
||||
;; left in place as ordinary statements and preserved into the
|
||||
;; generated C.
|
||||
(strip-header-comments fn-form (fn-header-length fn-form)))
|
||||
|
||||
(define (process-fn sex-fn-raw acc)
|
||||
(let-values (((doc sex-fn)
|
||||
|
||||
@@ -72,9 +72,10 @@
|
||||
(list)
|
||||
raw-forms)))
|
||||
|
||||
(define (public-fn-interface form)
|
||||
(define (public-fn-interface raw-form)
|
||||
;; (pub fn name args ret . body) -> prototype, keeping a docstring so
|
||||
;; the importer can emit it above the declaration
|
||||
(let ((form (strip-header-comments raw-form 5)))
|
||||
(match form
|
||||
(('pub 'fn name args ret)
|
||||
form)
|
||||
@@ -83,7 +84,7 @@
|
||||
(('pub 'fn name args ret (? string? doc) . _)
|
||||
`(pub fn ,name ,args ,ret ,doc))
|
||||
(('pub 'fn name args ret . _)
|
||||
`(pub fn ,name ,args ,ret))))
|
||||
`(pub fn ,name ,args ,ret)))))
|
||||
|
||||
;;; TODO: use semen facilities to analyze modules
|
||||
(define (process-public-interface-form form acc)
|
||||
@@ -92,8 +93,9 @@
|
||||
;; with external linkage
|
||||
(('pub 'fn . _)
|
||||
(cons (copy-form-source! form (public-fn-interface form)) acc))
|
||||
(('pub 'var name type . _)
|
||||
(cons (copy-form-source! form `(extern var ,name ,type)) acc))
|
||||
(('pub 'var . _)
|
||||
(match-let ((('pub 'var name type . _) (strip-header-comments form 4)))
|
||||
(cons (copy-form-source! form `(extern var ,name ,type)) acc)))
|
||||
(('pub (or 'define 'defmacro 'enum 'import 'include 'struct 'typedef 'union) . _)
|
||||
(cons (copy-form-source! form (cdr form)) acc))
|
||||
(('pub . _)
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
# It also checks what only a second translation unit can check: that an
|
||||
# imported type reaches the type database, by expanding a macro that
|
||||
# reads the imported struct's fields.
|
||||
#
|
||||
# The public forms carry comments in their headers, which the reduction
|
||||
# to a prototype and to an extern both have to look past.
|
||||
|
||||
SEXC ?= ../../sexc
|
||||
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
|
||||
(include stdio.h)
|
||||
|
||||
(pub var greet-count int 0)
|
||||
(pub var greet-count ;; a comment in the header of a public form is
|
||||
;; not part of it: what the importer is given has
|
||||
;; to be `extern int greet-count', not a form
|
||||
;; counted off by one
|
||||
int 0)
|
||||
|
||||
(pub struct greeting
|
||||
"A greeting to print."
|
||||
@@ -25,7 +29,8 @@
|
||||
(lambda (name field-type)
|
||||
`(printf "%s " ,(symbol->string name))))))
|
||||
|
||||
(pub fn greet ((name (* const char))) void
|
||||
(pub fn greet ;; ...and here the prototype would lose its return type
|
||||
((name (* const char))) void
|
||||
"Print a greeting for NAME."
|
||||
(++ greet-count)
|
||||
(printf "hello, %s\n" name))
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
set-working-directory
|
||||
to-absolute-pathname
|
||||
comment-form?
|
||||
strip-header-comments
|
||||
list-split
|
||||
list-join
|
||||
recons
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
set-working-directory
|
||||
to-absolute-pathname
|
||||
comment-form?
|
||||
strip-header-comments
|
||||
list-split
|
||||
list-join
|
||||
recons
|
||||
|
||||
15
utils.scm
15
utils.scm
@@ -45,6 +45,21 @@
|
||||
(define (comment-form? form)
|
||||
(and (pair? form) (eq? (car form) 'comment)))
|
||||
|
||||
;;; Remove the comment forms from the first COUNT elements of FORM --
|
||||
;;; its header -- so that the positional accessors reading it are not
|
||||
;;; shifted by one
|
||||
(define (strip-header-comments form count)
|
||||
;; This always rebuilds the list, so the location has to be carried
|
||||
;; over explicitly -- otherwise every form loses it
|
||||
(copy-form-source!
|
||||
form
|
||||
(let loop ((rest form) (kept 0) (acc (list)))
|
||||
(cond
|
||||
((null? rest) (reverse acc))
|
||||
((= kept count) (append (reverse acc) rest))
|
||||
((comment-form? (car rest)) (loop (cdr rest) kept acc))
|
||||
(else (loop (cdr rest) (+ kept 1) (cons (car rest) acc)))))))
|
||||
|
||||
(define (list-split src-list split-elt)
|
||||
;; split '(1 2 / 3 4 / 5 6) by '/ -> '((1 2) (3 4) (5 6))
|
||||
(fold (lambda (elt acc)
|
||||
|
||||
Reference in New Issue
Block a user