forked from alex-eg/sex
Compare commits
2 Commits
feature/pr
...
8588f5a531
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8588f5a531 | ||
|
|
05929951cb |
13
semen.scm
13
semen.scm
@@ -144,12 +144,15 @@
|
|||||||
(define (comment-form? f)
|
(define (comment-form? f)
|
||||||
(and (pair? f) (eq? (car f) 'comment)))
|
(and (pair? f) (eq? (car f) 'comment)))
|
||||||
|
|
||||||
|
(define (fn-header-length fn-form)
|
||||||
|
(if (memq (first fn-form) '(pub extern)) 5 4))
|
||||||
|
|
||||||
(define (strip-fn-header-comments fn-form)
|
(define (strip-fn-header-comments fn-form)
|
||||||
;; Remove comment forms from the function header
|
;; Remove comment forms from the function header
|
||||||
;; ([pub|extern] fn name arglist rettype) so the positional accessors
|
;; ([pub|extern] fn name arglist rettype) so the positional accessors
|
||||||
;; below are not shifted. Comments in the body are left in place as
|
;; below are not shifted. Comments in the body are left in place as
|
||||||
;; ordinary statements and preserved into the generated C.
|
;; ordinary statements and preserved into the generated C.
|
||||||
(let ((header-count (if (memq (car fn-form) '(pub extern)) 5 4)))
|
(let ((header-count (fn-header-length fn-form)))
|
||||||
;; This always rebuilds the list, so the location has to be carried
|
;; This always rebuilds the list, so the location has to be carried
|
||||||
;; over explicitly -- otherwise every function loses it
|
;; over explicitly -- otherwise every function loses it
|
||||||
(copy-form-source!
|
(copy-form-source!
|
||||||
@@ -265,13 +268,9 @@ Returns #f if the form is not a function, returns the form otherwise"
|
|||||||
"Returns all except body"
|
"Returns all except body"
|
||||||
(assert (sex-fn? fn-form)
|
(assert (sex-fn? fn-form)
|
||||||
(fmt #f "Form " fn-form " is not a function"))
|
(fmt #f "Form " fn-form " is not a function"))
|
||||||
(if (sex-fn-public? fn-form)
|
(take fn-form (fn-header-length fn-form)))
|
||||||
(take fn-form 5)
|
|
||||||
(take fn-form 4)))
|
|
||||||
|
|
||||||
(define (sex-fn-body fn-form)
|
(define (sex-fn-body fn-form)
|
||||||
(assert (sex-fn? fn-form)
|
(assert (sex-fn? fn-form)
|
||||||
(fmt #f "Form " fn-form " is not a function"))
|
(fmt #f "Form " fn-form " is not a function"))
|
||||||
(if (sex-fn-public? fn-form)
|
(drop fn-form (fn-header-length fn-form)))
|
||||||
(drop fn-form 5)
|
|
||||||
(drop fn-form 4)))
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
(chicken process-context)
|
(chicken process-context)
|
||||||
(chicken string)
|
(chicken string)
|
||||||
fmt
|
fmt
|
||||||
|
matchable
|
||||||
reader
|
reader
|
||||||
srfi-1
|
srfi-1
|
||||||
utils)
|
utils)
|
||||||
@@ -71,22 +72,33 @@
|
|||||||
(list)
|
(list)
|
||||||
raw-forms)))
|
raw-forms)))
|
||||||
|
|
||||||
|
(define (public-fn-interface form)
|
||||||
|
;; (pub fn name args ret . body) -> prototype, keeping a docstring so
|
||||||
|
;; the importer can emit it above the declaration
|
||||||
|
(match form
|
||||||
|
(('pub 'fn name args ret)
|
||||||
|
form)
|
||||||
|
(('pub 'fn name args ret ('comment . _) . rest)
|
||||||
|
(public-fn-interface `(pub fn ,name ,args ,ret ,@rest)))
|
||||||
|
(('pub 'fn name args ret (? string? doc) . _)
|
||||||
|
`(pub fn ,name ,args ,ret ,doc))
|
||||||
|
(('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)
|
||||||
(case (car form)
|
(match form
|
||||||
((pub)
|
;; Reduced to a prototype, still `pub', so the importer declares it
|
||||||
(case (cadr form)
|
;; with external linkage
|
||||||
;; A function is reduced to a prototype and keeps its `pub', so
|
(('pub 'fn . _)
|
||||||
;; the importing unit declares it with external linkage
|
(cons (copy-form-source! form (public-fn-interface form)) acc))
|
||||||
((fn)
|
(('pub 'var name type . _)
|
||||||
(cons (copy-form-source! form (take form 5)) acc))
|
(cons (copy-form-source! form `(extern var ,name ,type)) acc))
|
||||||
;; A variable becomes an `extern' declaration
|
(('pub (or 'define 'defmacro 'enum 'import 'include 'struct 'typedef 'union) . _)
|
||||||
((var)
|
|
||||||
(cons (copy-form-source! form (cons 'extern (take (cdr form) 3))) acc))
|
|
||||||
((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))))
|
(('pub . _)
|
||||||
(else acc)))
|
(sex-error form "pub must be followed by a definition" form))
|
||||||
|
(_ acc)))
|
||||||
|
|
||||||
(define (load-persistent-module-paths)
|
(define (load-persistent-module-paths)
|
||||||
(let ((sex-module-path-env-var
|
(let ((sex-module-path-env-var
|
||||||
|
|||||||
Reference in New Issue
Block a user