aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/control/function/inline.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/control/function/inline.lux')
-rw-r--r--stdlib/source/library/lux/control/function/inline.lux50
1 files changed, 50 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/control/function/inline.lux b/stdlib/source/library/lux/control/function/inline.lux
new file mode 100644
index 000000000..ef0836888
--- /dev/null
+++ b/stdlib/source/library/lux/control/function/inline.lux
@@ -0,0 +1,50 @@
+(.using
+ [library
+ [lux "*"
+ ["[0]" meta]
+ [abstract
+ ["[0]" monad {"+" do}]]
+ [control
+ ["<>" parser
+ ["<[0]>" code {"+" Parser}]]]
+ [data
+ [collection
+ ["[0]" list ("[1]#[0]" monad)]]]
+ ["[0]" macro
+ ["[0]" code]
+ [syntax {"+" syntax:}
+ ["|[0]|" export]]]]])
+
+(def: declaration
+ (Parser [Text (List Code)])
+ (<code>.form (<>.and <code>.local_symbol (<>.some <code>.any))))
+
+(def: inline
+ (Parser [Code [Text (List Code)] Code Code])
+ (|export|.parser
+ ($_ <>.and
+ ..declaration
+ <code>.any
+ <code>.any
+ )))
+
+(syntax: .public (inline: [[privacy [name parameters] type term] ..inline])
+ (do [! meta.monad]
+ [@ meta.current_module_name
+ g!parameters (|> (macro.symbol "parameter")
+ (list.repeated (list.size parameters))
+ (monad.all !))
+ .let [inlined (` (("lux in-module"
+ (~ (code.text @))
+ (.: (~ type)
+ (.function ((~ (code.local_symbol name)) (~+ parameters))
+ (~ term))))
+ (~+ (list#each (function (_ g!parameter)
+ (` ((~' ~) (~ g!parameter))))
+ g!parameters))))
+ g!parameters (|> g!parameters
+ (list#each (function (_ parameter)
+ (list parameter (` (~! <code>.any)))))
+ list#conjoint)]]
+ (in (list (` ((~! syntax:) (~ privacy) ((~ (code.local_symbol name)) [(~+ g!parameters)])
+ (.# (~! meta.monad) (~' in) (.list (.`' (~ inlined))))))))))