skill.lang.AND_LETSEQ

Last-modified: 2026-01-10 (土) 19:14:14
/******************************************************************************
 * 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]