feat: add assignment operator macros (#1320)

These macros apply an operation to the current value of a variable and
then set the variable to the result of the application. They are
effectively sugar for writing `(set! <var> (<op> <var> <val>))` and
should be familiar to those who have programmed in imperative languages
like C.

In Carp, all the underlying operations these macros use are interfaces,
so one can flexibly use them for more than just numeric types.

Example usage:

```clojure
(let-do [dial 0]
  ;; crank it up to 11!
  (while-do (dial < 12)
    (++ dial))
  dial)

;; expanded
(let-do [dial 0]
  ;; crank it up to 11!
  (while-do (dial < 12)
    (set! dial (inc dial)))
  dial)
```
This commit is contained in:
Scott Olsen 2021-09-27 04:15:54 -04:00 committed by GitHub
parent 0188264463
commit bd553fb78e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -309,6 +309,31 @@ the filename and module name are the same.")
(defmacro implements-all [mod :rest interfaces]
(cons 'do (map (curry implement-declaration mod) interfaces)))
(doc ++
"Sets the value of a variable to its current value incremented by one.")
(defmacro ++ [var]
(list 'set! var (list 'inc var)))
(doc --
"Sets the value of a variable to its current value decremented by one.")
(defmacro -- [var]
(list 'set! var (list 'dec var)))
(doc +=
"Sets the value of a variable to its current value plus `val`.")
(defmacro += [var val]
(list 'set! var (list '+ var val)))
(doc -=
"Sets the value of a variable to its current value minus `val`.")
(defmacro -= [var val]
(list 'set! var (list '- var val)))
(doc *=
"Sets the value of a variable to its current value multiplied by `val`.")
(defmacro *= [var val]
(list 'set! var (list '* var val)))
(defmodule Unsafe
(defmodule C
(defndynamic emit-c-line [append-strings args]