diff options
Diffstat (limited to 'stdlib/source/lux/language/compiler/synthesis/expression.lux')
-rw-r--r-- | stdlib/source/lux/language/compiler/synthesis/expression.lux | 99 |
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+) + ))) |