aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/lang/synthesis/function.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/lang/synthesis/function.lux')
-rw-r--r--stdlib/source/lux/lang/synthesis/function.lux49
1 files changed, 49 insertions, 0 deletions
diff --git a/stdlib/source/lux/lang/synthesis/function.lux b/stdlib/source/lux/lang/synthesis/function.lux
new file mode 100644
index 000000000..7b989d975
--- /dev/null
+++ b/stdlib/source/lux/lang/synthesis/function.lux
@@ -0,0 +1,49 @@
+(.module:
+ lux
+ (lux (control [monad #+ do]
+ [state])
+ (data [maybe]
+ [error]
+ (coll [list "list/" Monoid<List>]))
+ (lang [".L" analysis #+ Variable Analysis]))
+ [// #+ Arity Synthesizer]
+ [//loop])
+
+(def: nested?
+ (-> Arity Bool)
+ (n/> +1))
+
+## (def: (adjust-var outer var)
+## (-> Arity Variable Variable)
+## (|> outer dec .int (i/+ var)))
+
+(def: (unfold apply)
+ (-> Analysis [Analysis (List Analysis)])
+ (loop [apply apply
+ args (list)]
+ (case apply
+ (#analysisL.Apply arg func)
+ (recur func (#.Cons arg args))
+
+ _
+ [apply args])))
+
+(def: #export (apply synthesize)
+ (-> Synthesizer Synthesizer)
+ (function (_ exprA)
+ (let [[funcA argsA] (unfold exprA)]
+ (do (state.Monad<State'> error.Monad<Error>)
+ [funcS (synthesize funcA)
+ argsS (monad.map @ synthesize argsA)
+ locals //.locals]
+ (case funcS
+ (^ (//.function/abstraction functionS))
+ (wrap (|> functionS
+ (//loop.loop (get@ #//.environment functionS) locals argsS)
+ (maybe.default (//.function/apply [funcS argsS]))))
+
+ (^ (//.function/apply [funcS' argsS']))
+ (wrap (//.function/apply [funcS' (list/compose argsS' argsS)]))
+
+ _
+ (wrap (//.function/apply [funcS argsS])))))))