aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux')
-rw-r--r--stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux117
1 files changed, 117 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux
new file mode 100644
index 000000000..1d1021d11
--- /dev/null
+++ b/stdlib/source/library/lux/meta/compiler/language/lux/phase/generation/python/function.lux
@@ -0,0 +1,117 @@
+(.require
+ [library
+ [lux (.except function)
+ [abstract
+ ["[0]" monad (.only do)]]
+ [data
+ ["[0]" product]
+ [text
+ ["%" \\format (.only format)]]
+ [collection
+ ["[0]" list (.use "[1]#[0]" functor mix)]]]
+ [meta
+ [target
+ ["_" python (.only SVar Expression Statement)]]]]]
+ ["[0]" //
+ [runtime (.only Operation Phase Generator Phase! Generator!)]
+ ["[1][0]" reference]
+ ["[1][0]" case]
+ ["[1][0]" loop]
+ ["/[1]" //
+ ["[1][0]" reference]
+ ["//[1]" ///
+ [analysis (.only Environment Abstraction Reification Analysis)]
+ [synthesis (.only Synthesis)]
+ ["[1][0]" generation]
+ ["//[1]" ///
+ [arity (.only Arity)]
+ ["[1][0]" phase]
+ [reference
+ [variable (.only Register Variable)]]
+ [meta
+ [archive (.only Archive)
+ ["[0]" artifact]]
+ ["[0]" cache
+ [dependency
+ ["[1]" artifact]]]]]]]])
+
+(def .public (apply expression archive [functionS argsS+])
+ (Generator (Reification Synthesis))
+ (do [! ///////phase.monad]
+ [functionO (expression archive functionS)
+ argsO+ (monad.each ! (expression archive) argsS+)]
+ (in (_.apply argsO+ functionO))))
+
+(def .public capture
+ (-> Register SVar)
+ (|>> (///reference.foreign //reference.system) as_expected))
+
+(def (with_closure function_id @function inits function_definition)
+ (-> artifact.ID SVar (List (Expression Any)) (Statement Any) (Operation (Expression Any)))
+ (case inits
+ {.#End}
+ (do ///////phase.monad
+ [_ (/////generation.execute! function_definition)
+ _ (/////generation.save! function_id {.#None} function_definition)]
+ (in @function))
+
+ _
+ (do [! ///////phase.monad]
+ [.let [declaration (_.def @function
+ (|> (list.enumeration inits)
+ (list#each (|>> product.left ..capture)))
+ (all _.then
+ function_definition
+ (_.return @function)))]
+ _ (/////generation.execute! declaration)
+ _ (/////generation.save! function_id {.#None} declaration)]
+ (in (_.apply inits @function)))))
+
+(def input
+ (|>> ++ //case.register))
+
+(def .public (function statement expression archive [environment arity bodyS])
+ (-> Phase! (Generator (Abstraction Synthesis)))
+ (do [! ///////phase.monad]
+ [dependencies (cache.dependencies archive bodyS)
+ [[function_module function_artifact] body!] (/////generation.with_new_context archive dependencies
+ (/////generation.with_anchor 1
+ (statement expression archive bodyS)))
+ environment (monad.each ! (expression archive) environment)
+ .let [@curried (_.var "curried")
+ arityO (|> arity .int _.int)
+ @num_args (_.var "num_args")
+ @self (_.var (///reference.artifact [function_module function_artifact]))
+ apply_poly (.function (_ args func)
+ (_.apply (list (_.splat_poly args)) func))
+ initialize_self! (_.set (list (//case.register 0)) @self)
+ initialize! (list#mix (.function (_ post pre!)
+ (all _.then
+ pre!
+ (_.set (list (..input post)) (_.item (|> post .int _.int) @curried))))
+ initialize_self!
+ (list.indices arity))]]
+ (with_closure function_artifact @self environment
+ (_.def @self (list (_.poly @curried))
+ (all _.then
+ (_.set (list @num_args) (_.len/1 @curried))
+ (<| (_.if (|> @num_args (_.= arityO))
+ (<| (_.then initialize!)
+ //loop.set_scope
+ body!))
+ (_.if (|> @num_args (_.> arityO))
+ (let [arity_inputs (_.slice (_.int +0) arityO @curried)
+ extra_inputs (_.slice arityO @num_args @curried)]
+ (_.return (|> @self
+ (apply_poly arity_inputs)
+ (apply_poly extra_inputs)))))
+ ... (|> @num_args (_.< arityO))
+ (let [@next (_.var "next")
+ @missing (_.var "missing")]
+ (all _.then
+ (_.def @next (list (_.poly @missing))
+ (_.return (|> @self (apply_poly (|> @curried (_.+ @missing))))))
+ (_.return @next)
+ )))
+ )))
+ ))