aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/compiler/default/phase/analysis/macro.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/compiler/default/phase/analysis/macro.lux')
-rw-r--r--stdlib/source/lux/compiler/default/phase/analysis/macro.lux44
1 files changed, 44 insertions, 0 deletions
diff --git a/stdlib/source/lux/compiler/default/phase/analysis/macro.lux b/stdlib/source/lux/compiler/default/phase/analysis/macro.lux
new file mode 100644
index 000000000..c37375805
--- /dev/null
+++ b/stdlib/source/lux/compiler/default/phase/analysis/macro.lux
@@ -0,0 +1,44 @@
+(.module:
+ [lux #*
+ [control
+ [monad (#+ do)]]
+ [data
+ ["." error (#+ Error)]
+ [collection
+ ["." array (#+ Array)]]]
+ ["." host (#+ import:)]])
+
+(import: java/lang/reflect/Method
+ (invoke [Object (Array Object)] #try Object))
+
+(import: (java/lang/Class c)
+ (getMethod [String (Array (Class Object))] #try Method))
+
+(import: java/lang/Object
+ (getClass [] (Class 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)))
+ (function (_ compiler)
+ (do error.Monad<Error>
+ [apply-method (|> macro
+ (:coerce Object)
+ (Object::getClass [])
+ (Class::getMethod ["apply" _apply-args]))
+ 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 (Error [Lux (List Code)])
+ output))))