diff --git a/example/lambdas.sex b/example/lambdas.sex index 48eb54a..676eef2 100644 --- a/example/lambdas.sex +++ b/example/lambdas.sex @@ -10,12 +10,12 @@ (var sum-lambda (fn ((int) (int)) int) - (lambda ((a int) (b int)) int () + (lambda ((a int) (b int)) int (return (+ a b)))) (var sum-lambda-2 (fn ((int)) int) - (lambda ((a int)) int () + (lambda ((a int)) int (return (+ a 20)))) (printf "Hello from main fn!\n") @@ -24,28 +24,25 @@ (printf "Calling fn ptr: %d\n" (sum-fn a b)) (printf "Calling lambda: %d\n" (sum-lambda a b)) (printf "Calling other lambda: %d\n" (sum-lambda-2 a)) - (printf "Calling lambda inplace: %d\n" ((lambda ((a int) (b int)) int () + (printf "Calling lambda inplace: %d\n" ((lambda ((a int) (b int)) int (return (+ a b 100))) a b)) (var l-1 (fn ((int)) int) - (lambda ((a int)) int () + (lambda ((a int)) int (var l-2 (fn ((int)) int) - (lambda ((a int)) int () + (lambda ((a int)) int (return (+ 60 a)))) (return (+ 600 (l-2 a))))) (printf "Calling nested lambdas: %d\n" (l-1 6)) - ;; Not supported yet - ;; Closure - ;; (var (fn (fn ((int)) int) ((int))) make-adder - ;; (lambda (fn int ((int a))) () - ;; (return (lambda int ((int b)) (a) - ;; (return (+ a b)))))) + ;; Not supported yet -- captures belong to `closure' now, see + ;; Function-values.org + ;; (fn make-adder ((a int)) (closure ((int)) int) + ;; (return (closure ((b int)) int (a) + ;; (return (+ a b))))) ;; - ;; (var (fn int ((int))) add-10 - ;; (make-adder 10)) - ;; (var (fn int ((int))) add-20 - ;; (make-adder 20)) - ;; (printf "Calling closures: %d\n" (add-10 24)) + ;; (var add-10 (closure ((int)) int) (make-adder 10)) + ;; (var add-20 (closure ((int)) int) (make-adder 20)) + ;; (printf "Calling closures: %d %d\n" (add-10 24) (add-20 24)) (return 0)) diff --git a/semen.scm b/semen.scm index 4262fa1..0872ff5 100644 --- a/semen.scm +++ b/semen.scm @@ -242,7 +242,7 @@ (let ((lambda-name (make-lambda-name (hash-table-ref env :fn-name) (hash-table-ref env :lambda-counter)))) (set! (hash-table-ref env :lambda-aux-code) - (append (make-aux-lambda-struct lambda-name form) + (append (lift-lambda lambda-name form) (hash-table-ref env :lambda-aux-code))) (set! (hash-table-ref env :lambda-counter) (+ (hash-table-ref env :lambda-counter) 1)) @@ -253,11 +253,9 @@ (string->symbol (fmt #f "__lambda_" counter "_" enclosing-fn-name))) -(define (make-aux-lambda-struct name form) +(define (lift-lambda name form) (match form - (('lambda arglist ret-type captures . body) - ;; Captures are ignored for now, but - ;; we'll need them for TODO: closures support + (('lambda arglist ret-type . body) (process-fn (copy-form-source! form `(fn ,name ,arglist ,ret-type ,@body)) (list))) (else (sex-error form "malformed lambda" form)))) diff --git a/tests/sex-programs/lambdas.sex b/tests/sex-programs/lambdas.sex index 8de9a5d..0c67de7 100644 --- a/tests/sex-programs/lambdas.sex +++ b/tests/sex-programs/lambdas.sex @@ -22,21 +22,21 @@ (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 () + (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 () + ((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 () + (lambda ((x int)) int (var inner (fn ((int)) int) - (lambda ((y int)) int () + (lambda ((y int)) int (return (+ 60 y)))) (return (+ 600 (inner x))))) (printf "Nested lambdas: %d\n" (outer 6))