diff options
Diffstat (limited to 'stdlib/source/library/lux/meta/type/primitive.lux')
-rw-r--r-- | stdlib/source/library/lux/meta/type/primitive.lux | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/meta/type/primitive.lux b/stdlib/source/library/lux/meta/type/primitive.lux new file mode 100644 index 000000000..50c288e1c --- /dev/null +++ b/stdlib/source/library/lux/meta/type/primitive.lux @@ -0,0 +1,105 @@ +(.require + [library + [lux (.except) + ["[0]" meta] + [abstract + [monad (.only do)]] + [control + ["<>" parser (.use "[1]#[0]" monad)]] + [data + ["[0]" text (.use "[1]#[0]" equivalence)] + [collection + ["[0]" list (.use "[1]#[0]" functor)]]] + ["[0]" macro (.only) + ["^" pattern] + ["[0]" context] + ["[0]" code (.only) + ["<[1]>" \\parser (.only Parser)]] + [syntax (.only syntax) + ["|[0]|" export]]] + [meta + ["[0]" symbol (.use "[1]#[0]" codec)]]]] + ["[0]" //]) + +(type .public Frame + (Record + [#name Text + #type_vars (List Code) + #abstraction Code + #representation Code])) + +(context.def [frames expression declaration] Frame) + +(.def .public current + (Meta Frame) + (context.peek ..frames)) + +(.def .public (specific name) + (-> Text (Meta Frame)) + (context.search ..frames (|>> (the #name) (text#= name)))) + +(def cast + (Parser [(Maybe Text) Code]) + (<>.either (<>.and (<>.maybe <code>.local) <code>.any) + (<>.and (<>#in {.#None}) <code>.any))) + +(with_template [<name> <from> <to>] + [(def .public <name> + (syntax (_ [[frame value] ..cast]) + (do meta.monad + [[name type_vars abstraction representation] (case frame + {.#Some frame} + (..specific frame) + + {.#None} + ..current)] + (in (list (` ((~! //.as) [(~+ type_vars)] (~ <from>) (~ <to>) + (~ value))))))))] + + [abstraction representation abstraction] + [representation abstraction representation] + ) + +(def declarationP + (Parser [Text (List Text)]) + (<>.either (<code>.form (<>.and <code>.local (<>.some <code>.local))) + (<>.and <code>.local (at <>.monad in (list))))) + +(def abstract + (Parser [Code [Text (List Text)] Code (List Code)]) + (|export|.parser + (all <>.and + ..declarationP + <code>.any + (<>.some <code>.any) + ))) + +... TODO: Make sure the generated code always gets optimized away. +... (This applies to uses of "abstraction" and "representation") +(def .public primitive + (syntax (_ [[export_policy [name type_vars] representation_type primitives] + ..abstract]) + (do meta.monad + [current_module meta.current_module_name + g!Representation (macro.symbol "Representation") + .let [type_varsC (list#each code.local type_vars) + abstraction_declaration (` ((~ (code.local name)) (~+ type_varsC))) + representation_declaration (` ((~ g!Representation) (~+ type_varsC)))]] + (..declaration [name type_varsC abstraction_declaration representation_declaration] + (` (.these (type (~ export_policy) (~ abstraction_declaration) + (Primitive (~ (code.text (symbol#encoded [current_module name]))) + [(~+ type_varsC)])) + (type (~ representation_declaration) + (~ representation_type)) + (~+ primitives))))))) + +(def selection + (Parser [(List Code) Code]) + (<>.either (<>.and (<>#each (|>> list) <code>.any) <code>.any) + (<>.and (<>#in (list)) <code>.any))) + +(def .public transmutation + (syntax (_ [[specific value] ..selection]) + (in (list (` (.|> (~ value) + (..representation (~+ specific)) + (..abstraction (~+ specific)))))))) |