aboutsummaryrefslogtreecommitdiff
path: root/new-luxc/source/luxc/lang/translation/python/function.jvm.lux
diff options
context:
space:
mode:
Diffstat (limited to 'new-luxc/source/luxc/lang/translation/python/function.jvm.lux')
-rw-r--r--new-luxc/source/luxc/lang/translation/python/function.jvm.lux99
1 files changed, 99 insertions, 0 deletions
diff --git a/new-luxc/source/luxc/lang/translation/python/function.jvm.lux b/new-luxc/source/luxc/lang/translation/python/function.jvm.lux
new file mode 100644
index 000000000..97b936fc4
--- /dev/null
+++ b/new-luxc/source/luxc/lang/translation/python/function.jvm.lux
@@ -0,0 +1,99 @@
+(.module:
+ lux
+ (lux (control [monad #+ do]
+ pipe)
+ (data [product]
+ [text]
+ text/format
+ (coll [list "list/" Functor<List> Fold<List>]))
+ [macro])
+ (luxc ["&" lang]
+ (lang ["ls" synthesis]
+ [".L" variable #+ Variable]
+ (host [python #+ Expression Statement @@])))
+ [//]
+ (// [".T" reference]))
+
+(def: #export (translate-apply translate functionS argsS+)
+ (-> (-> ls.Synthesis (Meta Expression)) ls.Synthesis (List ls.Synthesis) (Meta Expression))
+ (do macro.Monad<Meta>
+ [functionO (translate functionS)
+ argsO+ (monad.map @ translate argsS+)]
+ (wrap (python.apply argsO+ functionO))))
+
+(def: $curried (python.var "curried"))
+
+(def: (input-declaration register)
+ (python.set! (list (referenceT.variable (n/inc register)))
+ (python.nth (|> register nat-to-int python.int)
+ (@@ $curried))))
+
+(def: (with-closure function-name inits function-definition)
+ (-> Text (List Expression) Statement (Meta Expression))
+ (let [$closure (python.var (format function-name "___CLOSURE"))]
+ (case inits
+ #.Nil
+ (do macro.Monad<Meta>
+ [_ (//.save function-definition)]
+ (wrap (python.global function-name)))
+
+ _
+ (do macro.Monad<Meta>
+ [_ (//.save (python.def! $closure
+ (|> (list.enumerate inits)
+ (list/map (|>> product.left referenceT.closure)))
+ ($_ python.then!
+ function-definition
+ (python.return! (python.global function-name)))))]
+ (wrap (python.apply inits (@@ $closure)))))))
+
+(def: #export (translate-function translate env arity bodyS)
+ (-> (-> ls.Synthesis (Meta Expression))
+ (List Variable) ls.Arity ls.Synthesis
+ (Meta Expression))
+ (do macro.Monad<Meta>
+ [[function-name bodyO] (//.with-sub-context
+ (do @
+ [function-name //.context]
+ (//.with-anchor [function-name +1]
+ (translate bodyS))))
+ closureO+ (monad.map @ referenceT.translate-variable env)
+ #let [args-initsO+ (|> (list.n/range +0 (n/dec arity))
+ (list/map input-declaration)
+ (case> #.Nil
+ python.no-op!
+
+ (#.Cons head tail)
+ (list/fold python.then! head tail)))
+ arityO (|> arity nat-to-int python.int)
+ @curried (@@ $curried)
+ $num_args (python.var "num_args")
+ @num_args (@@ $num_args)
+ $function (python.var function-name)
+ @function (@@ $function)]]
+ (with-closure function-name closureO+
+ (python.def! $function (list (python.poly $curried))
+ ($_ python.then!
+ (let [@len (python.global "len")]
+ (python.set! (list $num_args) (python.apply (list @curried) @len)))
+ (python.if! (python.= arityO @num_args)
+ ($_ python.then!
+ (python.set! (list (referenceT.variable +0)) @function)
+ args-initsO+
+ (python.while! (python.bool true)
+ (python.return! bodyO)))
+ (python.if! (python.> arityO @num_args)
+ (let [arity-args (python.slice (python.int 0) arityO @curried)
+ output-func-args (python.slice arityO @num_args @curried)]
+ (python.return! (|> @function
+ (python.apply-poly (list) arity-args)
+ (python.apply-poly (list) output-func-args))))
+ (let [$next (python.var "next")
+ $missing (python.var "missing")]
+ ($_ python.then!
+ (python.def! $next (list (python.poly $missing))
+ (python.return! (|> @function
+ (python.apply-poly (list) (|> @curried
+ (python.+ (@@ $missing)))))))
+ (python.return! (@@ $next)))))))))
+ ))