minor-language-improvements #38
2
Makefile
2
Makefile
@@ -94,7 +94,7 @@ sextest:
|
|||||||
cp ./tools/sextest/sextest .
|
cp ./tools/sextest/sextest .
|
||||||
|
|
||||||
SEX_TEST_PROGRAMS = hello-world lists comments unicode serialize features \
|
SEX_TEST_PROGRAMS = hello-world lists comments unicode serialize features \
|
||||||
feature-flags
|
feature-flags lambdas
|
||||||
|
|
||||||
# Multi-module linking is checked end to end; see tests/modules/Makefile.
|
# Multi-module linking is checked end to end; see tests/modules/Makefile.
|
||||||
check-modules: sexc
|
check-modules: sexc
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
(pub fn main () int
|
(pub fn main () int
|
||||||
(var a int 10)
|
(var a int 10)
|
||||||
(var b int 20)
|
(var b int 20)
|
||||||
(var (fn ((int) (int)) int) sum-fn sum)
|
(var sum-fn (fn ((int) (int)) int) sum)
|
||||||
|
|
||||||
(var (fn ((int) (int)) int) sum-lambda
|
(var sum-lambda (fn ((int) (int)) int)
|
||||||
|
|
||||||
(lambda ((a int) (b int)) int ()
|
(lambda ((a int) (b int)) int ()
|
||||||
(return (+ a b))))
|
(return (+ a b))))
|
||||||
|
|
||||||
(var (fn ((int)) int) sum-lambda-2
|
(var sum-lambda-2 (fn ((int)) int)
|
||||||
|
|
||||||
(lambda ((a int)) int ()
|
(lambda ((a int)) int ()
|
||||||
(return (+ a 20))))
|
(return (+ a 20))))
|
||||||
@@ -28,9 +28,9 @@
|
|||||||
(return (+ a b 100)))
|
(return (+ a b 100)))
|
||||||
a b))
|
a b))
|
||||||
|
|
||||||
(var (fn ((int)) int) l-1
|
(var l-1 (fn ((int)) int)
|
||||||
(lambda ((a int)) int ()
|
(lambda ((a int)) int ()
|
||||||
(var (fn ((int)) int) l-2
|
(var l-2 (fn ((int)) int)
|
||||||
(lambda ((a int)) int ()
|
(lambda ((a int)) int ()
|
||||||
(return (+ 60 a))))
|
(return (+ 60 a))))
|
||||||
(return (+ 600 (l-2 a)))))
|
(return (+ 600 (l-2 a)))))
|
||||||
|
|||||||
@@ -380,8 +380,8 @@ forms, and what remains."
|
|||||||
(map arg-type (remove comment-form? form)))
|
(map arg-type (remove comment-form? form)))
|
||||||
|
|
||||||
(define (walk-function form)
|
(define (walk-function form)
|
||||||
;; (fn ret-type name arglist body) -> normal function
|
;; (fn name arglist ret-type body) -> normal function
|
||||||
;; (fn ret-type name arglist) -> prototype
|
;; (fn name arglist ret-type) -> prototype
|
||||||
(if (>= (length form) 5)
|
(if (>= (length form) 5)
|
||||||
(walk-fn-def form)
|
(walk-fn-def form)
|
||||||
(cons '%prototype (cdr (walk-fn-def form)))))
|
(cons '%prototype (cdr (walk-fn-def form)))))
|
||||||
|
|||||||
@@ -255,10 +255,10 @@
|
|||||||
|
|
||||||
(define (make-aux-lambda-struct name form)
|
(define (make-aux-lambda-struct name form)
|
||||||
(match form
|
(match form
|
||||||
(('lambda ret-type arglist captures . body)
|
(('lambda arglist ret-type captures . body)
|
||||||
;; Captures are ignored for now, but
|
;; Captures are ignored for now, but
|
||||||
;; we'll need them for TODO: closures support
|
;; we'll need them for TODO: closures support
|
||||||
(process-fn (copy-form-source! form `(fn ,ret-type ,name ,arglist ,@body))
|
(process-fn (copy-form-source! form `(fn ,name ,arglist ,ret-type ,@body))
|
||||||
(list)))
|
(list)))
|
||||||
(else (sex-error form "malformed lambda" form))))
|
(else (sex-error form "malformed lambda" form))))
|
||||||
|
|
||||||
|
|||||||
44
tests/sex-programs/lambdas.sex
Normal file
44
tests/sex-programs/lambdas.sex
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
(input)
|
||||||
|
(output "Named fn through a pointer: 30"
|
||||||
|
"Lambda through a pointer: 30"
|
||||||
|
"Lambda called in place: 130"
|
||||||
|
"Nested lambdas: 666")
|
||||||
|
(return 0)
|
||||||
|
|
||||||
|
;;; Lambdas are lifted into toplevel functions by semen, so what this
|
||||||
|
;;; really checks is that the lifted `fn' comes out in the argument
|
||||||
|
;;; order the writer expects -- (fn name arglist ret-type . body).
|
||||||
|
|
||||||
|
(include stdio.h)
|
||||||
|
|
||||||
|
(fn sum ((a int) (b int)) int
|
||||||
|
(return (+ a b)))
|
||||||
|
|
||||||
|
(pub fn main () int
|
||||||
|
(var a int 10)
|
||||||
|
(var b int 20)
|
||||||
|
|
||||||
|
(var sum-fn (fn ((int) (int)) int) sum)
|
||||||
|
(printf "Named fn through a pointer: %d\n" (sum-fn a b))
|
||||||
|
|
||||||
|
(var sum-lambda (fn ((int) (int)) int)
|
||||||
|
(lambda ((a int) (b int)) int ()
|
||||||
|
(return (+ a b))))
|
||||||
|
(printf "Lambda through a pointer: %d\n" (sum-lambda a b))
|
||||||
|
|
||||||
|
(printf "Lambda called in place: %d\n"
|
||||||
|
((lambda ((a int) (b int)) int ()
|
||||||
|
(return (+ a b 100)))
|
||||||
|
a b))
|
||||||
|
|
||||||
|
;; A lambda inside a lambda: the inner one is lifted out of a
|
||||||
|
;; function that is itself being lifted
|
||||||
|
(var outer (fn ((int)) int)
|
||||||
|
(lambda ((x int)) int ()
|
||||||
|
(var inner (fn ((int)) int)
|
||||||
|
(lambda ((y int)) int ()
|
||||||
|
(return (+ 60 y))))
|
||||||
|
(return (+ 600 (inner x)))))
|
||||||
|
(printf "Nested lambdas: %d\n" (outer 6))
|
||||||
|
|
||||||
|
(return 0))
|
||||||
Reference in New Issue
Block a user