54 lines
1.9 KiB
Scheme
54 lines
1.9 KiB
Scheme
;;; A module. Everything marked `pub' forms its public interface;
|
|
;;; everything else is private to this file.
|
|
;;;
|
|
;;; Importing a module does not link it: it pastes the declarations, so
|
|
;;; the compiled object still has to be handed to the C compiler. See
|
|
;;; greet-app.sex.
|
|
|
|
(include stdio.h)
|
|
|
|
(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."
|
|
((text (* const char)) (times int)))
|
|
|
|
(pub enum mood (cheerful grumpy))
|
|
|
|
(pub typedef greeting-t (struct greeting))
|
|
|
|
;;; Compile-time reflection across the module boundary: both the macro
|
|
;;; and the struct it asks about are exported, and the importing unit
|
|
;;; has to know the struct's fields to expand this.
|
|
(pub defmacro (describe-fields type)
|
|
`(do ,@(map-fields type
|
|
(lambda (name field-type)
|
|
`(printf "%s " ,(symbol->string name))))))
|
|
|
|
(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))
|
|
|
|
;;; A closure type crossing the boundary. Both units generate the
|
|
;;; struct for this signature independently, so they have to agree on
|
|
;;; its tag and its layout, or the value is passed wrong and nothing
|
|
;;; says so.
|
|
(pub fn make-adder ((n int)) (closure ((int)) int)
|
|
(return (closure ((b int)) int (n)
|
|
(return (+ n b)))))
|
|
|
|
;;; The other direction: a closure built by the importer, whose code
|
|
;;; pointer is static in *its* object, called from here
|
|
(pub fn apply-twice ((f (closure ((int)) int)) (x int)) int
|
|
(return (f (f x))))
|
|
|
|
;;; Not `pub': invisible to importers, and static in the generated C.
|
|
(fn unused-helper () void
|
|
(printf "private\n"))
|