aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/lang/macro.lux
blob: 17ed2436ba29b86c34b96e618fdec8fd625f96bc (plain)
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
(.module:
  lux
  (lux (control [monad #+ do])
       (data ["e" error])
       [macro]
       [host])
  (luxc (lang [".L" host]
              (translation (jvm [".T" common])))))

(for {"JVM" (as-is (host.import: java/lang/reflect/Method
                     (invoke [Object (Array Object)] #try Object))
                   (host.import: (java/lang/Class c)
                     (getMethod [String (Array (Class Object))] #try Method))
                   (host.import: java/lang/Object)
                   (def: _object-class (Class Object) (host.class-for Object))
                   (def: _apply-args
                     (Array (Class Object))
                     (|> (host.array (Class Object) +2)
                         (host.array-write +0 _object-class)
                         (host.array-write +1 _object-class)))
                   (def: #export (expand macro inputs)
                     (-> Macro (List Code) (Meta (List Code)))
                     (do macro.Monad<Meta>
                       [class (commonT.load-class hostL.function-class)]
                       (function (_ compiler)
                         (do e.Monad<Error>
                           [apply-method (Class::getMethod ["apply" _apply-args] class)
                            output (Method::invoke [(:coerce Object macro)
                                                    (|> (host.array Object +2)
                                                        (host.array-write +0 (:coerce Object inputs))
                                                        (host.array-write +1 (:coerce Object compiler)))]
                                                   apply-method)]
                           (:coerce (e.Error [Lux (List Code)])
                                    output))))))
      })