mirror of
https://github.com/carp-lang/Carp.git
synced 2024-10-26 13:51:50 +03:00
feat: allow for multibranches in case (#1276)
This commit is contained in:
parent
ca0f9f7d4f
commit
0adc1abd50
@ -141,6 +141,12 @@ Example:
|
|||||||
(defmacro unless [condition form]
|
(defmacro unless [condition form]
|
||||||
(list 'if condition (list) form))
|
(list 'if condition (list) form))
|
||||||
|
|
||||||
|
(hidden treat-case-handler)
|
||||||
|
(defndynamic treat-case-handler [name handler]
|
||||||
|
(if (and (list? handler) (> (length handler) 1) (= ':or (car handler)))
|
||||||
|
(cons 'or (map (fn [val] (list '= name val)) (cdr handler)))
|
||||||
|
(list '= name handler)))
|
||||||
|
|
||||||
(hidden case-internal)
|
(hidden case-internal)
|
||||||
(defndynamic case-internal [name xs]
|
(defndynamic case-internal [name xs]
|
||||||
(if (= (length xs) 0)
|
(if (= (length xs) 0)
|
||||||
@ -150,24 +156,28 @@ Example:
|
|||||||
(if (= (length xs) 1)
|
(if (= (length xs) 1)
|
||||||
(car xs)
|
(car xs)
|
||||||
(list 'if
|
(list 'if
|
||||||
(list '= name (car xs))
|
(treat-case-handler name (car xs))
|
||||||
(cadr xs)
|
(cadr xs)
|
||||||
(case-internal name (cddr xs)))))))
|
(case-internal name (cddr xs)))))))
|
||||||
|
|
||||||
(doc case "takes a form and a list of branches which are value and operation
|
(doc case "takes a form and a list of branches which are value and operation
|
||||||
pairs. If a value matches, the operation is executed. It takes a catch-all else
|
pairs. If a value matches (or any in a list of values preced by `:or`), the
|
||||||
branch that is executed if nothing matches.
|
operation is executed. It takes a catch-all else branch that is executed if
|
||||||
|
nothing matches.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```
|
```
|
||||||
(case (+ 10 1)
|
(case (+ 10 1)
|
||||||
10 (println* \"nope\")
|
10 (println* \"nope\")
|
||||||
11 (println* \"yup\")
|
11 (println* \"yup\")
|
||||||
|
(:or 12 13) (println* \"multibranch, but nope\")
|
||||||
(println* \"else branch\")
|
(println* \"else branch\")
|
||||||
)
|
)
|
||||||
```")
|
```")
|
||||||
(defmacro case [form :rest branches]
|
(defmacro case [form :rest branches]
|
||||||
(case-internal form branches))
|
(let [name (gensym)]
|
||||||
|
(list 'let [name form]
|
||||||
|
(case-internal name branches))))
|
||||||
|
|
||||||
(defmodule Dynamic
|
(defmodule Dynamic
|
||||||
(doc flip
|
(doc flip
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
(doc gensym-with "Generates symbols dynamically, based on a symbol name.")
|
(doc gensym-with "Generates symbols dynamically, based on a symbol name.")
|
||||||
(defndynamic gensym-with [x]
|
(defndynamic gensym-with [x]
|
||||||
(do
|
(do
|
||||||
(set! *gensym-counter* (inc *gensym-counter*))
|
(set! *gensym-counter* (+ *gensym-counter* 1))
|
||||||
(Symbol.concat [x (Symbol.from *gensym-counter*)])))
|
(Symbol.concat [x (Symbol.from *gensym-counter*)])))
|
||||||
|
|
||||||
(doc gensym "Generates symbols dynamically as needed.")
|
(doc gensym "Generates symbols dynamically as needed.")
|
||||||
|
@ -34,6 +34,12 @@
|
|||||||
1 true
|
1 true
|
||||||
false))
|
false))
|
||||||
|
|
||||||
|
(defn test-case-multi []
|
||||||
|
(case 1
|
||||||
|
2 false
|
||||||
|
(:or 1 3) true
|
||||||
|
false))
|
||||||
|
|
||||||
(defmacro test-not [a] (not a))
|
(defmacro test-not [a] (not a))
|
||||||
(defmacro test-< [a b] (< a b))
|
(defmacro test-< [a b] (< a b))
|
||||||
(defmacro test-> [a b] (> a b))
|
(defmacro test-> [a b] (> a b))
|
||||||
@ -84,6 +90,9 @@
|
|||||||
(assert-true test
|
(assert-true test
|
||||||
(test-case-select)
|
(test-case-select)
|
||||||
"case correctly selects branch")
|
"case correctly selects branch")
|
||||||
|
(assert-true test
|
||||||
|
(test-case-multi)
|
||||||
|
"case correctly selects multibranch")
|
||||||
(assert-true test
|
(assert-true test
|
||||||
(test-comment)
|
(test-comment)
|
||||||
"comment ignores input")
|
"comment ignores input")
|
||||||
|
Loading…
Reference in New Issue
Block a user