A app/src/react-macros.fnl => app/src/react-macros.fnl +61 -0
@@ 0,0 1,61 @@
+(local unpack (or unpack table.unpack))
+(fn push [tab v]
+ (let [len (# tab)
+ i (+ len 1)]
+ (tset tab i v)))
+
+(fn js! [val]
+ (if (table? val)
+ (let [RETURN (gensym)
+ dolist `(do)]
+ (if (sequence? val)
+ (do
+ (push dolist `(local @RETURN (js.new js.global.Array)))
+ (each [i v (ipairs val)]
+ (push dolist `(tset @RETURN @(- i 1) @(js! v))))
+ (push dolist RETURN)
+ dolist)
+
+ (do (push dolist `(local @RETURN (js.new js.global.Object)))
+ (each [k v (pairs val)]
+ (push dolist `(tset @RETURN @(tostring k) @(js! v))))
+ (push dolist RETURN)
+ dolist)))
+ val))
+
+(fn create-component [el attrs ...]
+ (let [ATTRS (gensym)
+ CHILDREN (gensym)
+ children [...]
+ child-list []]
+ (each [i v (ipairs children)]
+ (push child-list `@(js! v)))
+ `(do (local @ATTRS @(js! (or attrs {})))
+ (: React :createElement @el @ATTRS
+ @(unpack child-list)))))
+
+(fn c! [arg1 ...]
+ (if (sequence? arg1)
+ (let [[name attrs] arg1
+ child-forms []
+ evaluated-child-forms []]
+ (for [i 3 (# arg1)] ;; skip name and attrs
+ (push child-forms (. arg1 i)))
+ (each [_ child-form (ipairs child-forms)]
+ ;; FIXME: this will eventually blow the stack
+ (push evaluated-child-forms
+ (if (sequence? child-form) (c! child-form)
+ child-form)))
+ (create-component name attrs (unpack evaluated-child-forms)))
+
+ ;; else
+ (create-component arg1 ...)))
+
+(fn component! [name args ...]
+ (let [padded-args `[_ @(unpack args)]]
+ `(fn @name @padded-args @...)))
+
+
+{:js! js!
+ :c! c!
+ :component! component!}