forked from alex-eg/sex
implement closures
This commit is contained in:
@@ -10,14 +10,17 @@
|
||||
#
|
||||
# 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.
|
||||
# reads the imported struct's fields; and that a closure type crossing
|
||||
# the boundary works both ways -- one built in the module and called
|
||||
# here, one built here and called there, through a code pointer that is
|
||||
# static in the other object.
|
||||
#
|
||||
# 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
|
||||
|
||||
EXPECTED = hello, world\nhello, sex\n2 greetings\ntext times \ntext times \nmood 1
|
||||
EXPECTED = hello, world\nhello, sex\n2 greetings\ntext times \ntext times \nmood 1\nclosure 15 21 201
|
||||
|
||||
check:
|
||||
@$(SEXC) greet.sex -c -o greet.o
|
||||
|
||||
@@ -26,4 +26,11 @@
|
||||
(printf "\n")
|
||||
(var m (enum mood) grumpy)
|
||||
(printf "mood %d\n" m)
|
||||
|
||||
(var add-10 (closure ((int)) int) (make-adder 10))
|
||||
(printf "closure %d %d" (add-10 5) (apply-twice add-10 1))
|
||||
(var base int 100)
|
||||
(var here (closure ((int)) int)
|
||||
(closure ((x int)) int (base) (return (+ base x))))
|
||||
(printf " %d\n" (apply-twice here 1))
|
||||
(return 0))
|
||||
|
||||
@@ -35,6 +35,19 @@
|
||||
(++ 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"))
|
||||
|
||||
Reference in New Issue
Block a user