Add type db, some nice macro features and a brand new SDL3 example #27
14
semen.scm
14
semen.scm
@@ -93,17 +93,9 @@
|
|||||||
(else (sex-error sex-form "unknown top level form" sex-form))))
|
(else (sex-error sex-form "unknown top level form" sex-form))))
|
||||||
|
|
||||||
(define (process-imports module-public-forms acc)
|
(define (process-imports module-public-forms acc)
|
||||||
;; Recursively process imports: register public macros, cons all
|
;; consume (import ...) form and process imports so
|
||||||
;; other public things to our acc
|
;; data types end up in types db
|
||||||
(if (null? module-public-forms) acc
|
(fold match-sex-form acc module-public-forms))
|
||||||
(match (car module-public-forms)
|
|
||||||
(('defmacro . rest)
|
|
||||||
(defmacro rest)
|
|
||||||
(process-imports (cdr module-public-forms) acc))
|
|
||||||
(else
|
|
||||||
(process-imports (cdr module-public-forms)
|
|
||||||
(cons (car module-public-forms)
|
|
||||||
acc))))))
|
|
||||||
|
|
||||||
(define (macro-expand form)
|
(define (macro-expand form)
|
||||||
"Walk the form recursively and expand all macros, until none is left."
|
"Walk the form recursively and expand all macros, until none is left."
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
(define +persistent-module-paths+ (list))
|
(define +persistent-module-paths+ (list))
|
||||||
|
|
||||||
|
;;; for guarding against multiple imports (sort of mandatory #pragma
|
||||||
|
;;; once)
|
||||||
|
(define +imported-modules+ (list))
|
||||||
|
|
||||||
(define (get-modules-public-forms module-list)
|
(define (get-modules-public-forms module-list)
|
||||||
;; Module list is a list of symbols
|
;; Module list is a list of symbols
|
||||||
;; How Sex handles modules:
|
;; How Sex handles modules:
|
||||||
@@ -29,7 +33,11 @@
|
|||||||
(let ((module-path (locate-module name)))
|
(let ((module-path (locate-module name)))
|
||||||
(assert module-path (fmt #f "Failed to find module " name " in "
|
(assert module-path (fmt #f "Failed to find module " name " in "
|
||||||
(get-module-paths)))
|
(get-module-paths)))
|
||||||
(read-public-interface module-path)))
|
(if (member module-path +imported-modules+)
|
||||||
|
(list)
|
||||||
|
(begin
|
||||||
|
(set! +imported-modules+ (cons module-path +imported-modules+))
|
||||||
|
(read-public-interface module-path)))))
|
||||||
|
|
||||||
(define (get-module-paths)
|
(define (get-module-paths)
|
||||||
(cons (current-directory)
|
(cons (current-directory)
|
||||||
|
|||||||
@@ -7,10 +7,14 @@
|
|||||||
# module's object survives being passed after `--'. Get any of them
|
# module's object survives being passed after `--'. Get any of them
|
||||||
# wrong and this fails to link -- or, in the `pub var' case, links and
|
# wrong and this fails to link -- or, in the `pub var' case, links and
|
||||||
# quietly counts into a private copy.
|
# quietly counts into a private copy.
|
||||||
|
#
|
||||||
|
# It also checks what only a second translation unit can check: that an
|
||||||
|
# imported type reaches the type database, by expanding a macro that
|
||||||
|
# reads the imported struct's fields.
|
||||||
|
|
||||||
SEXC ?= ../../sexc
|
SEXC ?= ../../sexc
|
||||||
|
|
||||||
EXPECTED = hello, world\nhello, sex\n2 greetings
|
EXPECTED = hello, world\nhello, sex\n2 greetings\ntext times
|
||||||
|
|
||||||
check:
|
check:
|
||||||
@$(SEXC) greet.sex -c -o greet.o
|
@$(SEXC) greet.sex -c -o greet.o
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
;;; as a prototype and `greet-count' as an extern. Both keep external
|
;;; as a prototype and `greet-count' as an extern. Both keep external
|
||||||
;;; linkage, so they refer to the one definition in greet.o rather than
|
;;; linkage, so they refer to the one definition in greet.o rather than
|
||||||
;;; to private copies.
|
;;; to private copies.
|
||||||
|
;;;
|
||||||
|
;;; Also check that import populates type-database, by means of
|
||||||
|
;;; describe-fields macro, which should work on imported type.
|
||||||
|
|
||||||
(include stdio.h)
|
(include stdio.h)
|
||||||
|
|
||||||
@@ -16,4 +19,6 @@
|
|||||||
(greet "world")
|
(greet "world")
|
||||||
(greet "sex")
|
(greet "sex")
|
||||||
(printf "%d greetings\n" greet-count)
|
(printf "%d greetings\n" greet-count)
|
||||||
|
(describe-fields greeting)
|
||||||
|
(printf "\n")
|
||||||
(return 0))
|
(return 0))
|
||||||
|
|||||||
@@ -9,6 +9,16 @@
|
|||||||
|
|
||||||
(pub var greet-count int 0)
|
(pub var greet-count int 0)
|
||||||
|
|
||||||
|
(pub struct greeting ((text (* const char)) (times int)))
|
||||||
|
|
||||||
|
;;; 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 ((name (* const char))) void
|
(pub fn greet ((name (* const char))) void
|
||||||
(++ greet-count)
|
(++ greet-count)
|
||||||
(printf "hello, %s\n" name))
|
(printf "hello, %s\n" name))
|
||||||
|
|||||||
Reference in New Issue
Block a user