;'<<SPEC'
<!--
Copyright (c) 2012-2024, Chris Pressey, Cat's Eye Technologies.
This file is distributed under a 2-clause BSD license. See LICENSES/ dir.
SPDX-License-Identifier: LicenseRef-BSD-2-Clause-X-Robin
-->
### `bind-vals` ###
-> Tests for functionality "Evaluate Robin Expression (with Stdlib)"
`bind-vals` is a fexpr for bindings the components of a possibly-deep list
to the identifiers given in another possibly-deep list (of symbols).
It is similar to `bind-args` but doesn't evaluate the values that are
being bound.
| (bind-vals (a b) (literal (1 2))
| (list a b))
= (1 2)
Expressions in the list of values are not evaluated.
| (bind-vals (a b) (literal ((subtract 5 4) (subtract 10 1)))
| (list a b))
= ((subtract 5 4) (subtract 10 1))
It handles deep lists.
| (bind-vals (a (b c)) (literal (1 (2 3)))
| (list a b c))
= (1 2 3)
This is how it might be used in a fexpr definition.
| (bind add (fexpr (args env)
| (bind-vals (a b) args
| (subtract a (subtract 0 b))))
| (add 4 5))
= 9
| (bind add (fexpr (args env)
| (bind-vals (a b) args
| (subtract a (subtract 0 b))))
| (add 4 (add 5 6)))
? (abort (expected-number (add 5 6)))
| (bind transducer (fexpr (args env)
| (bind-vals ((event-type event-payload) state) args
| (list state (list event-type event-payload))))
| (transducer (click (button 12345)) 0))
= (0 (click (button 12345)))
'<<SPEC'
(define bind-vals
(fexpr (args env)
(let (
(id-list (head args))
(val-list (eval env (head (tail args))))
(expr (head (tail (tail args))))
(bind-vals-r (fexpr (args env)
(let (
(self (eval env (head args)))
(id-list (eval env (head (tail args))))
(val-list (eval env (head (tail (tail args)))))
(expr (eval env (head (tail (tail (tail args))))))
)
(if (equal? id-list ())
expr
(let ((id (head id-list)) (val (head val-list)))
(if (list? id)
(self self id val
(self self (tail id-list) (tail val-list) expr))
(list (literal bind) id (list (literal literal) val)
(self self (tail id-list) (tail val-list) expr)))))))))
(eval env (bind-vals-r bind-vals-r id-list val-list expr)))))