mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
* feat: generalized (and) and (or) to handle any number of parameters * feat!: removed (and*) and (or*) macros * chore: worked around compiler issue for unit test * fix: unit test in ./test/macro.carp Co-authored-by: guberatsie <gunnar.bernhardt@siemens.com>
82 lines
2.4 KiB
Plaintext
82 lines
2.4 KiB
Plaintext
(doc Quasiquote "is a mechanism for quotation with code interspersed. See
|
|
the documentation of [`quasiquote`](#quasiquote) or the [high level
|
|
overview](https://github.com/carp-lang/Carp/blob/master/docs/Quasiquotation.md)
|
|
for details.")
|
|
(defmodule Quasiquote
|
|
(doc unquote "unquotes (i.e. evaluates) an expression `form` inside a
|
|
quasiquote. It will generate an error message when used outside a
|
|
`quasiquote` form.
|
|
|
|
Example:
|
|
|
|
```
|
|
(defdynamic x 2)
|
|
|
|
(quasiquote (+ (unquote x) 1)) ; => (+ 2 1)
|
|
```")
|
|
(defmacro unquote [form]
|
|
(macro-error "unquotes need to be wrapped inside quasiquotes."))
|
|
|
|
(doc unquote-splicing "unquotes (i.e. evaluates) an expression `form` inside a
|
|
quasiquote and splices it in, i.e. flattens the expression. It will
|
|
generate an error message when used outside a `quasiquote` form.
|
|
|
|
Example:
|
|
|
|
```
|
|
(defdynamic x '(1 2)
|
|
|
|
(quasiquote (+ (unquote-splicing x))) ; => (+ 1 2)
|
|
```")
|
|
(defmacro unquote-splicing [form]
|
|
(macro-error "unquotes need to be wrapped inside quasiquotes."))
|
|
|
|
(hidden quasiquote-list)
|
|
(defndynamic quasiquote-list [form]
|
|
(let [app (car form)]
|
|
(cond
|
|
(= app 'quasiquote) form
|
|
(and (= app 'unquote) (= (length form) 2))
|
|
(cadr form)
|
|
(= app 'unquote)
|
|
(macro-error "unquote takes exactly one argument.")
|
|
(and (= app 'unquote-splicing) (= (length form) 2))
|
|
(macro-error "unquote-splicing needs an enclosing list.")
|
|
(= app 'unquote-splicing)
|
|
(macro-error "unquote-splicing takes exactly one argument.")
|
|
(reduce
|
|
(fn [acc elem]
|
|
(if (and (list? elem)
|
|
(= (length elem) 2)
|
|
(= (car elem) 'unquote-splicing))
|
|
(list 'append acc (cadr elem))
|
|
(list 'cons-last (quasiquote- elem) acc)))
|
|
'()
|
|
form))))
|
|
|
|
(hidden quasiquote-)
|
|
(defndynamic quasiquote- [form]
|
|
(cond
|
|
(and (list? form) (> (length form) 0))
|
|
(quasiquote-list form)
|
|
(array? form)
|
|
(collect-into (map quasiquote- form) array)
|
|
(list 'quote form)))
|
|
|
|
(doc quasiquote "is a quotation that may have expressions inside it in the
|
|
form of [`unquote`](#unquote) and [`unquote-splicing`](#unquote-splicing).
|
|
|
|
Example:
|
|
```
|
|
(defdynamic x 1)
|
|
(defdynamic y '(2 3 4))
|
|
|
|
(quasiquote (1 (unquote x) (unquote-splicing y))) ; => (1 1 2 3 4)
|
|
; using the reader macros
|
|
`(1 %x %@y)) ; => (1 1 2 3 4)
|
|
```")
|
|
(defmacro quasiquote [form]
|
|
(quasiquote- form)))
|
|
|
|
(use Quasiquote)
|