minor-language-improvements #38
2
Makefile
2
Makefile
@@ -94,7 +94,7 @@ sextest:
|
||||
cp ./tools/sextest/sextest .
|
||||
|
||||
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.
|
||||
check-modules: sexc
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
(pub fn main () int
|
||||
(var a int 10)
|
||||
(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 ()
|
||||
(return (+ a b))))
|
||||
|
||||
(var (fn ((int)) int) sum-lambda-2
|
||||
(var sum-lambda-2 (fn ((int)) int)
|
||||
|
||||
(lambda ((a int)) int ()
|
||||
(return (+ a 20))))
|
||||
@@ -28,9 +28,9 @@
|
||||
(return (+ a b 100)))
|
||||
a b))
|
||||
|
||||
(var (fn ((int)) int) l-1
|
||||
(var l-1 (fn ((int)) int)
|
||||
(lambda ((a int)) int ()
|
||||
(var (fn ((int)) int) l-2
|
||||
(var l-2 (fn ((int)) int)
|
||||
(lambda ((a int)) int ()
|
||||
(return (+ 60 a))))
|
||||
(return (+ 600 (l-2 a)))))
|
||||
|
||||
@@ -380,8 +380,8 @@ forms, and what remains."
|
||||
(map arg-type (remove comment-form? form)))
|
||||
|
||||
(define (walk-function form)
|
||||
;; (fn ret-type name arglist body) -> normal function
|
||||
;; (fn ret-type name arglist) -> prototype
|
||||
;; (fn name arglist ret-type body) -> normal function
|
||||
;; (fn name arglist ret-type) -> prototype
|
||||
(if (>= (length form) 5)
|
||||
(walk-fn-def form)
|
||||
(cons '%prototype (cdr (walk-fn-def form)))))
|
||||
|
||||
@@ -255,10 +255,10 @@
|
||||
|
||||
(define (make-aux-lambda-struct name form)
|
||||
(match form
|
||||
(('lambda ret-type arglist captures . body)
|
||||
(('lambda arglist ret-type captures . body)
|
||||
;; Captures are ignored for now, but
|
||||
;; 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)))
|
||||
(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