/******************************************************************************
* AND_LETSEQ
* Ver: 20220701
*
* Derived from SRFI-2 and-let*.
* (https://srfi.schemers.org/srfi-2/srfi-2.html)
******************************************************************************/
;
(define_syntax AND_LETSEQ
(syntax_rules ()
;
((AND_LETSEQ ())
; then
t)
;
((AND_LETSEQ () bodies ...)
; then
(let () bodies ...))
;
;; Transforming in following way makes implementation easier,
;; but by not adopting this method, the original form can be
;; displayed as much as possible with an error message.
;;
;; ((AND_LETSEQ (clauses ...) bodies ...)
;; (AND_LETSEQ (clauses ... (let () bodies ...))))
;
; --------------------------------------------------------------------------
;
;; Null clause is allowed because null means boolean false in SKILL.
;; In this case, processing following clauses and bodies is not needed.
((AND_LETSEQ (() clauses ...) bodies ...)
; then
nil)
;
; --------------------------------------------------------------------------
; Binding clause
;
;; List-style var is invalid.
((AND_LETSEQ (((list_style_var ...) expr) clauses ...) bodies ...)
; then
(error "Invalid AND_LETSEQ form (list-style variable is invalid): %L" (quote (AND_LETSEQ (((list_style_var ...) expr) clauses ...) bodies ...))))
;
((AND_LETSEQ ((var expr)))
; then
(let ((var expr))
var))
;
((AND_LETSEQ ((var expr)) body)
; then
(let ((var expr))
(and var body)))
;
((AND_LETSEQ ((var expr)) bodies ...)
; then
(let ((var expr))
(and var (begin bodies ...))))
;
((AND_LETSEQ ((var expr) clauses ...) bodies ...)
; then
(let ((var expr))
(and var (AND_LETSEQ (clauses ...) bodies ...))))
;
; --------------------------------------------------------------------------
; Guard clause
;
;; First guard clause -- in case of (expr exprs ...) style.
((AND_LETSEQ (((guard_clause_head guard_clause_tail ...)) clauses ...) bodies ...)
; then
(AND_LETSEQ
"AND_LETSEQ clauses:" (clauses ...)
"Guard clauses:" ((guard_clause_head guard_clause_tail ...))
"Bodies:" (bodies ...)))
;
((AND_LETSEQ ((list_style_clause ...) clauses ...) bodies ...)
; then
(error "Invalid AND_LETSEQ form (any list-style clause other than (var expr) and ((expr exprs ...)) is invalid): %L" (quote (AND_LETSEQ ((list_style_clause ...) clauses ...) bodies ...))))
;
;; First guard clause -- in case of var style.
((AND_LETSEQ (var clauses ...) bodies ...)
; then
(AND_LETSEQ
"AND_LETSEQ clauses:" (clauses ...)
"Guard clauses:" (var)
"Bodies:" (bodies ...)))
;
((AND_LETSEQ
"AND_LETSEQ clauses:" ()
"Guard clauses:" (guard_clause)
"Bodies:" ())
; then
guard_clause)
;
((AND_LETSEQ
"AND_LETSEQ clauses:" ()
"Guard clauses:" (guard_clauses ...)
"Bodies:" ())
; then
(and guard_clauses ...))
;
((AND_LETSEQ
"AND_LETSEQ clauses:" ()
"Guard clauses:" (guard_clauses ...)
"Bodies:" (bodies ...))
; then
(and guard_clauses ...
(AND_LETSEQ () bodies ...)))
;
;; Null clause is allowed because null means boolean false in SKILL.
;; In this case, processing following clauses and bodies is not needed.
;; But evaluating preceding guard clauses is needed,
;; because some of them can have side-effect.
((AND_LETSEQ
"AND_LETSEQ clauses:" (() clauses ...)
"Guard clauses:" ()
"Bodies:" (bodies ...))
; then
nil)
;
((AND_LETSEQ
"AND_LETSEQ clauses:" (() clauses ...)
"Guard clauses:" (guard_clauses ...)
"Bodies:" (bodies ...))
; then
(and guard_clauses ... nil))
;
;; (expr exprs ...) style guard clause:
((AND_LETSEQ
"AND_LETSEQ clauses:" (((guard_clause_head guard_clause_tail ...)) clauses ...)
"Guard clauses:" (guard_clauses ...)
"Bodies:" (bodies ...))
; then
(AND_LETSEQ
"AND_LETSEQ clauses:" (clauses ...)
"Guard clauses:" (guard_clauses ... (guard_clause_head guard_clause_tail ...))
"Bodies:" (bodies ...)))
;
;; In case a binding clause exists after one/more preceding guard_clause(s):
((AND_LETSEQ
"AND_LETSEQ clauses:" ((var expr) clauses ...)
"Guard clauses:" (guard_clauses ...)
"Bodies:" (bodies ...))
; then
(and guard_clauses ...
(AND_LETSEQ ((var expr) clauses ...) bodies ...)))
;
;; Any list-style clause other than (var expr) and ((expr exprs ...)) is invalid.
((AND_LETSEQ
"AND_LETSEQ clauses:" ((list_style_clause ...) clauses ...)
"Guard clauses:" (guard_clauses ...)
"Bodies:" (bodies ...))
; then
(error "Invalid AND_LETSEQ form (any list-style clause other than (var expr) and ((expr exprs ...)) is invalid): %L" (quote (AND_LETSEQ ((list_style_clause ...) clauses ...) bodies ...))))
;
;; var must be a symbol.
((AND_LETSEQ
"AND_LETSEQ clauses:" (var clauses ...)
"Guard clauses:" (guard_clauses ...)
"Bodies:" (bodies ...))
; then
(AND_LETSEQ
"AND_LETSEQ clauses:" (clauses ...)
"Guard clauses:" (guard_clauses ... var)
"Bodies:" (bodies ...)))
;
; ==========================================================================
;
((AND_LETSEQ args ...)
(error "Invalid AND_LETSEQ form: %L" (quote (AND_LETSEQ args ...))))))
;
; ==============================================================================
; [EOF]