123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- ;; This library makes use of the CK macro base library, to
- ;; define more CK style macros.
- (library (ck-extra)
- (export c-and-raise
- c-replace-placeholder
- c-list->vector
- c-vector->list
- <?>)
- (import (except (rnrs base) let-values)
- (only (guile)
- lambda* lambda λ
- raise-exception)
- (ck-base)
- (exceptions))
- (define <?> '<?>)
- ;; ==========================
- ;; additional CK style macros
- ;; ==========================
- ;; `c-and-raise` needs to be a macro, because its
- ;; arguments must not be evaluated, before we can look at
- ;; them and build up an expression, which contains the
- ;; argument in its unevaluated form. We need the not yet
- ;; evaluated form, to have a readable and understandable
- ;; error message, when raising an exception. The exception
- ;; will contain the literal expression, which failed to
- ;; evaluate to a truthy value.
- (define-syntax c-and-raise
- (syntax-rules (quote)
- ;; `and-raise` takes a list of expressions to check as
- ;; an argument.
- [(c-and-raise stack
- 'function-name
- '(list
- (op args* ...)
- expr* ...))
- (ck stack
- '(cond
- ;; Check the first condition.
- [(op args* ...)
- (ck stack
- ;; Check the rest of the conditions.
- (c-and-raise (quote function-name)
- (quote (list expr* ...))))]
- [else
- (raise-exception
- (make-exception-contract-violated-compound
- "contract violated"
- (quote function-name)
- (quote (op args* ...))))]))]
- [(c-and-raise stack
- (quote function-name)
- (quote (list #|nothing|#)))
- (ck stack (quote #t))]))
- ;; Usage example:
- #;(ck ()
- (c-and-raise
- 'unknown-origin
- '(list (= 1 1) (= 2 3))))
- ;; (define result 3)
- ;; (ck ()
- ;; (c-and-raise
- ;; 'unknown-origin
- ;; (c-map '(c-replace-placeholder 'result)
- ;; '(list (= 1 <?>) (= 2 3)))))
- ;; (define result 3)
- ;; (ck ()
- ;; (c-and-raise
- ;; 'my-function-name
- ;; (c-map '(c-replace-placeholder 'result)
- ;; '(list (= 1 <?>) (= 2 3)))))
- (define-syntax c-replace-placeholder
- (syntax-rules (quote <?>)
- ;; Replace the placeholder, if it is the expression.
- [(c-replace-placeholder stack 'result (quote <?>))
- (ck stack (quote result))]
- ;; Only one expression remaining.
- [(c-replace-placeholder stack 'result '(expr))
- (ck stack
- (c-cons
- (c-replace-placeholder 'result 'expr)
- '()))]
- ;; There are multiple expressions left. (Case of single
- ;; expression is matched earlier.)
- [(c-replace-placeholder stack 'result '(expr expr* ...))
- (ck stack
- (c-cons
- (c-replace-placeholder 'result 'expr)
- (c-replace-placeholder 'result '(expr* ...))))]
- ;; Take care of vectors.
- [(c-replace-placeholder stack 'result (quote #(expr* ...)))
- (ck stack
- (c-list->vector
- (c-replace-placeholder 'result
- (c-vector->list
- '#(expr* ...)))))]
- ;; Or a non-compound expression, which is not the
- ;; placeholder.
- [(c-replace-placeholder stack 'result 'expr)
- (ck stack 'expr)]
- ))
- ;; Example usage:
- ;; (ck () (c-replace-placeholder 'result ''(1 2 <>)))
- ;; (ck ()
- ;; (c-replace-placeholder 'result
- ;; '(apply + (list 1 2 <?>))))
- ;; (ck ()
- ;; (c-map '(c-replace-placeholder 'result)
- ;; '((= 1 <?>))))
- (define-syntax c-list->vector
- (syntax-rules (quote list)
- [(_ stack (quote '(expr* ...)))
- ;; Replace with call to (vector ...), because #()
- ;; syntax does not evaluate the things inside
- ;; parentheses. If there was a reference to a
- ;; variable in there, it would be seen as a symbol
- ;; only. The actual value would not be in there.
- (ck stack (quote (vector expr* ...)))]
- [(_ stack (quote (list expr* ...)))
- (ck stack (quote (vector expr* ...)))]
- ;; Fallback for better error message.
- [(_ stack (quote other* ...))
- (syntax-error
- "could not recognize list in expression"
- other* ...)]))
- ;; Example usage:
- ;; (ck ()
- ;; (c-list->vector ''(a b c)))
- ;; (ck ()
- ;; (c-list->vector '(list 1 2 3)))
- (define-syntax c-vector->list
- (syntax-rules (quote list)
- [(_ stack (quote #(expr* ...)))
- (ck stack (quote '(expr* ...)))]
- [(_ stack (quote (vector expr* ...)))
- (ck stack (quote (list expr* ...)))]
- ;; Fallback for better error message.
- [(_ stack (quote other* ...))
- (syntax-error
- "could not recognize vector in expression"
- other* ...)])))
|