look past comments in a public form's header
This commit is contained in:
18
semen.scm
18
semen.scm
@@ -142,21 +142,9 @@
|
|||||||
;;; Fn processing
|
;;; Fn processing
|
||||||
|
|
||||||
(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)
|
||||||
;; ([pub|extern] fn name arglist rettype) so the positional accessors
|
(strip-header-comments fn-form
|
||||||
;; below are not shifted. Comments in the body are left in place as
|
(if (memq (car fn-form) '(pub extern)) 5 4)))
|
||||||
;; ordinary statements and preserved into the generated C.
|
|
||||||
(let ((header-count (if (memq (car fn-form) '(pub extern)) 5 4)))
|
|
||||||
;; 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* ((sex-fn (strip-fn-header-comments sex-fn-raw))
|
(let* ((sex-fn (strip-fn-header-comments sex-fn-raw))
|
||||||
|
|||||||
@@ -79,10 +79,16 @@
|
|||||||
;; A function is reduced to a prototype and keeps its `pub', so
|
;; A function is reduced to a prototype and keeps its `pub', so
|
||||||
;; the importing unit declares it with external linkage
|
;; the importing unit declares it with external linkage
|
||||||
((fn)
|
((fn)
|
||||||
(cons (copy-form-source! form (take form 5)) acc))
|
(cons (copy-form-source!
|
||||||
|
form
|
||||||
|
(take (strip-header-comments form 5) 5))
|
||||||
|
acc))
|
||||||
;; A variable becomes an `extern' declaration
|
;; A variable becomes an `extern' declaration
|
||||||
((var)
|
((var)
|
||||||
(cons (copy-form-source! form (cons 'extern (take (cdr form) 3))) acc))
|
(cons (copy-form-source!
|
||||||
|
form
|
||||||
|
(cons 'extern (take (cdr (strip-header-comments form 4)) 3)))
|
||||||
|
acc))
|
||||||
((define defmacro enum import include struct typedef union)
|
((define defmacro enum import include struct typedef union)
|
||||||
(cons (copy-form-source! form (cdr form)) acc))
|
(cons (copy-form-source! form (cdr form)) acc))
|
||||||
(else (sex-error form "pub must be followed by a definition" form))))
|
(else (sex-error form "pub must be followed by a definition" form))))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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 ((text (* const char)) (times int)))
|
(pub struct greeting ((text (* const char)) (times int)))
|
||||||
|
|
||||||
@@ -23,7 +27,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
|
||||||
(++ greet-count)
|
(++ greet-count)
|
||||||
(printf "hello, %s\n" name))
|
(printf "hello, %s\n" name))
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
15
utils.scm
15
utils.scm
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user