minor-language-improvements #38

Merged
pkulev merged 3 commits from minor-language-improvements into main 2026-09-30 00:31:41 +02:00
5 changed files with 54 additions and 10 deletions
Showing only changes of commit 26e8e6c374 - Show all commits

View File

@@ -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

View File

@@ -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)))))

View File

@@ -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)))))

View File

@@ -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))))

View 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))