look past comments in a public form's header

This commit is contained in:
2026-09-21 00:56:26 +03:00
parent 534e9ef56b
commit ee053e35c9
7 changed files with 45 additions and 29 deletions

View File

@@ -204,21 +204,10 @@
acc))) acc)))
(define (strip-fn-header-comments fn-form) (define (strip-fn-header-comments fn-form)
;; Remove comment forms from the function header ;; ([pub|extern] fn name arglist rettype). Comments in the body are
;; ([pub|extern] fn name arglist rettype) so the positional accessors ;; left in place as ordinary statements and preserved into the
;; below are not shifted. Comments in the body are left in place as ;; generated C.
;; ordinary statements and preserved into the generated C. (strip-header-comments fn-form (fn-header-length fn-form)))
(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))))))))
(define (process-fn sex-fn-raw acc) (define (process-fn sex-fn-raw acc)
(let-values (((doc sex-fn) (let-values (((doc sex-fn)

View File

@@ -72,18 +72,19 @@
(list) (list)
raw-forms))) raw-forms)))
(define (public-fn-interface form) (define (public-fn-interface raw-form)
;; (pub fn name args ret . body) -> prototype, keeping a docstring so ;; (pub fn name args ret . body) -> prototype, keeping a docstring so
;; the importer can emit it above the declaration ;; the importer can emit it above the declaration
(match form (let ((form (strip-header-comments raw-form 5)))
(('pub 'fn name args ret) (match form
form) (('pub 'fn name args ret)
(('pub 'fn name args ret ('comment . _) . rest) form)
(public-fn-interface `(pub fn ,name ,args ,ret ,@rest))) (('pub 'fn name args ret ('comment . _) . rest)
(('pub 'fn name args ret (? string? doc) . _) (public-fn-interface `(pub fn ,name ,args ,ret ,@rest)))
`(pub fn ,name ,args ,ret ,doc)) (('pub 'fn name args ret (? string? doc) . _)
(('pub 'fn name args ret . _) `(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 ;;; TODO: use semen facilities to analyze modules
(define (process-public-interface-form form acc) (define (process-public-interface-form form acc)
@@ -92,8 +93,9 @@
;; with external linkage ;; with external linkage
(('pub 'fn . _) (('pub 'fn . _)
(cons (copy-form-source! form (public-fn-interface form)) acc)) (cons (copy-form-source! form (public-fn-interface form)) acc))
(('pub 'var name type . _) (('pub 'var . _)
(cons (copy-form-source! form `(extern var ,name ,type)) acc)) (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) . _) (('pub (or 'define 'defmacro 'enum 'import 'include 'struct 'typedef 'union) . _)
(cons (copy-form-source! form (cdr form)) acc)) (cons (copy-form-source! form (cdr form)) acc))
(('pub . _) (('pub . _)

View File

@@ -11,6 +11,9 @@
# It also checks what only a second translation unit can check: that an # It also checks what only a second translation unit can check: that an
# imported type reaches the type database, by expanding a macro that # imported type reaches the type database, by expanding a macro that
# reads the imported struct's fields. # 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 SEXC ?= ../../sexc

View File

@@ -7,7 +7,11 @@
(include stdio.h) (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 (pub struct greeting
"A greeting to print." "A greeting to print."
@@ -25,7 +29,8 @@
(lambda (name field-type) (lambda (name field-type)
`(printf "%s " ,(symbol->string name)))))) `(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." "Print a greeting for NAME."
(++ greet-count) (++ greet-count)
(printf "hello, %s\n" name)) (printf "hello, %s\n" name))

View File

@@ -3,6 +3,7 @@
set-working-directory set-working-directory
to-absolute-pathname to-absolute-pathname
comment-form? comment-form?
strip-header-comments
list-split list-split
list-join list-join
recons recons

View File

@@ -3,6 +3,7 @@
set-working-directory set-working-directory
to-absolute-pathname to-absolute-pathname
comment-form? comment-form?
strip-header-comments
list-split list-split
list-join list-join
recons recons

View File

@@ -45,6 +45,21 @@
(define (comment-form? form) (define (comment-form? form)
(and (pair? form) (eq? (car form) 'comment))) (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) (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)