;;; 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"))