aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/tool/compiler/meta/cache/module.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/tool/compiler/meta/cache/module.lux')
-rw-r--r--stdlib/source/library/lux/tool/compiler/meta/cache/module.lux98
1 files changed, 98 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/tool/compiler/meta/cache/module.lux b/stdlib/source/library/lux/tool/compiler/meta/cache/module.lux
new file mode 100644
index 000000000..e61b8cad2
--- /dev/null
+++ b/stdlib/source/library/lux/tool/compiler/meta/cache/module.lux
@@ -0,0 +1,98 @@
+(.using
+ [library
+ [lux {"-" Module}
+ [abstract
+ ["[0]" monad {"+" do}]]
+ [control
+ ["[0]" maybe ("[1]#[0]" functor)]
+ ["[0]" try {"+" Try}]
+ ["[0]" state]
+ [function
+ ["[0]" memo {"+" Memo}]]]
+ [data
+ ["[0]" text
+ ["%" format {"+" format}]]
+ [collection
+ ["[0]" list ("[1]#[0]" functor mix)]
+ ["[0]" dictionary {"+" Dictionary}]
+ ["[0]" set {"+" Set}]]]]]
+ [///
+ ["[0]" archive {"+" Output Archive}
+ [key {"+" Key}]
+ ["[0]" descriptor {"+" Module Descriptor}]
+ ["[0]" document {"+" Document}]]])
+
+(type: .public Ancestry
+ (Set Module))
+
+(def: fresh
+ Ancestry
+ (set.empty text.hash))
+
+(type: .public Graph
+ (Dictionary Module Ancestry))
+
+(def: empty
+ Graph
+ (dictionary.empty text.hash))
+
+(def: .public modules
+ (-> Graph (List Module))
+ dictionary.keys)
+
+(type: .public Dependency
+ (Record
+ [#module Module
+ #imports Ancestry]))
+
+(def: .public graph
+ (-> (List Dependency) Graph)
+ (list#mix (function (_ [module imports] graph)
+ (dictionary.has module imports graph))
+ ..empty))
+
+(def: (ancestry archive)
+ (-> Archive Graph)
+ (let [memo (: (Memo Module Ancestry)
+ (function (_ again module)
+ (do [! state.monad]
+ [.let [parents (case (archive.find module archive)
+ {try.#Success [descriptor document]}
+ (value@ descriptor.#references descriptor)
+
+ {try.#Failure error}
+ ..fresh)]
+ ancestors (monad.each ! again (set.list parents))]
+ (in (list#mix set.union parents ancestors)))))
+ ancestry (memo.open memo)]
+ (list#mix (function (_ module memory)
+ (if (dictionary.key? memory module)
+ memory
+ (let [[memory _] (ancestry [memory module])]
+ memory)))
+ ..empty
+ (archive.archived archive))))
+
+(def: (dependency? ancestry target source)
+ (-> Graph Module Module Bit)
+ (let [target_ancestry (|> ancestry
+ (dictionary.value target)
+ (maybe.else ..fresh))]
+ (set.member? target_ancestry source)))
+
+(type: .public Order
+ (List [Module [archive.ID [Descriptor (Document .Module) Output]]]))
+
+(def: .public (load_order key archive)
+ (-> (Key .Module) Archive (Try Order))
+ (let [ancestry (..ancestry archive)]
+ (|> ancestry
+ dictionary.keys
+ (list.sorted (..dependency? ancestry))
+ (monad.each try.monad
+ (function (_ module)
+ (do try.monad
+ [module_id (archive.id module archive)
+ [descriptor document output] (archive.find module archive)
+ document (document.marked? key document)]
+ (in [module [module_id [descriptor document output]]])))))))