/
core.cljc
62 lines (47 loc) · 1.63 KB
/
core.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
(ns allpa.core
#?(:clj (:require [clojure.string :as string]
[clojure.walk :as walk])
:cljs (:require-macros [allpa.core :refer [varg#]])))
;; math
(defn power [b e]
(if (< e 0) 0
#?(:clj (int (Math/floor (Math/pow b e)))
:cljs (.round js/Math (.floor js/Math (.pow js/Math b e))))))
(def p2 (partial power 2))
;; util
(defn parse-int
([s] (parse-int s nil))
([s default]
(let [tried (try
#?(:cljs (js/parseInt s 10)
:clj (Integer/parseInt s))
#?(:cljs (catch js/Object e default)
:clj (catch Exception e default)))]
(if (int? tried) tried default))))
;; i hate defrecord/defprotocol
(def mk #(assoc %2 ::type %1))
(def -default ::-default)
(def type ::type)
(def id ::id)
(def set-id #(assoc %1 ::id %2))
(defn match [funcs & last-args]
(fn [obj]
(let [val (or (type obj) obj)
args (conj last-args obj)
f (or (get funcs val) (-default funcs))]
(if (fn? f)
(apply f args)
(let [[get-drill-obj drill-funcs] f]
((apply match drill-funcs args)
(apply get-drill-obj args)))))))
;; macros
#?(:clj
(defmacro varg# [& statements]
(let [args (gensym "args")]
`(fn [& ~args]
~@(->> statements
(walk/postwalk (fn [sym]
(let [sym-name (if (symbol? sym) (name sym) "")]
(if (string/starts-with? sym-name "%")
`(nth ~args ~(-> sym-name (subs 1) (parse-int -1) dec) nil)
sym)))))))))