aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/language/compiler/synthesis/expression.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/language/compiler/synthesis/expression.lux')
-rw-r--r--stdlib/source/lux/language/compiler/synthesis/expression.lux99
1 files changed, 99 insertions, 0 deletions
diff --git a/stdlib/source/lux/language/compiler/synthesis/expression.lux b/stdlib/source/lux/language/compiler/synthesis/expression.lux
new file mode 100644
index 000000000..6db9a8fd5
--- /dev/null
+++ b/stdlib/source/lux/language/compiler/synthesis/expression.lux
@@ -0,0 +1,99 @@
+(.module:
+ [lux #- primitive]
+ (lux (control [monad #+ do]
+ ["ex" exception #+ exception:])
+ (data [maybe]
+ (collection [list "list/" Functor<List>]
+ ["dict" dictionary #+ Dictionary])))
+ [///reference]
+ [///compiler "operation/" Monad<Operation>]
+ [///analysis #+ Analysis]
+ [///extension #+ Extension]
+ [// #+ Synthesis]
+ [//function]
+ [//case])
+
+(exception: #export (unknown-synthesis-extension {name Text})
+ name)
+
+(def: (primitive analysis)
+ (-> ///analysis.Primitive //.Primitive)
+ (case analysis
+ #///analysis.Unit
+ (#//.Text //.unit)
+
+ (^template [<analysis> <synthesis>]
+ (<analysis> value)
+ (<synthesis> value))
+ ([#///analysis.Bool #//.Bool]
+ [#///analysis.Frac #//.F64]
+ [#///analysis.Text #//.Text])
+
+ (^template [<analysis> <synthesis>]
+ (<analysis> value)
+ (<synthesis> (.i64 value)))
+ ([#///analysis.Nat #//.I64]
+ [#///analysis.Int #//.I64]
+ [#///analysis.Rev #//.I64])))
+
+(def: #export (synthesizer extensions)
+ (-> (Extension ///extension.Synthesis) //.Synthesizer)
+ (function (synthesize analysis)
+ (case analysis
+ (#///analysis.Primitive analysis')
+ (operation/wrap (#//.Primitive (..primitive analysis')))
+
+ (#///analysis.Structure composite)
+ (case (///analysis.variant analysis)
+ (#.Some variant)
+ (do ///compiler.Monad<Operation>
+ [valueS (synthesize (get@ #///analysis.value variant))]
+ (wrap (#//.Structure (#//.Variant (set@ #///analysis.value valueS variant)))))
+
+ _
+ (do ///compiler.Monad<Operation>
+ [tupleS (monad.map @ synthesize (///analysis.tuple analysis))]
+ (wrap (#//.Structure (#//.Tuple tupleS)))))
+
+ (#///analysis.Apply _)
+ (//function.apply (|>> synthesize //.indirectly) analysis)
+
+ (#///analysis.Function environmentA bodyA)
+ (//function.function synthesize environmentA bodyA)
+
+ (#///analysis.Extension name args)
+ (case (dict.get name extensions)
+ #.None
+ (///compiler.throw unknown-synthesis-extension name)
+
+ (#.Some extension)
+ (extension (|>> synthesize //.indirectly) args))
+
+ (#///analysis.Reference reference)
+ (case reference
+ (#///reference.Constant constant)
+ (operation/wrap (#//.Reference reference))
+
+ (#///reference.Variable var)
+ (do ///compiler.Monad<Operation>
+ [resolver //.resolver]
+ (case var
+ (#///reference.Local register)
+ (do @
+ [arity //.scope-arity]
+ (wrap (if (//function.nested? arity)
+ (if (n/= +0 register)
+ (|> (dec arity)
+ (list.n/range +1)
+ (list/map (|>> //.variable/local))
+ [(//.variable/local +0)]
+ //.function/apply)
+ (#//.Reference (#///reference.Variable (//function.adjust arity false var))))
+ (#//.Reference (#///reference.Variable var)))))
+
+ (#///reference.Foreign register)
+ (wrap (|> resolver (dict.get var) (maybe.default var) #///reference.Variable #//.Reference)))))
+
+ (#///analysis.Case inputA branchesAB+)
+ (//case.synthesize (|>> synthesize //.indirectly) inputA branchesAB+)
+ )))