aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/type/primitive.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/meta/type/primitive.lux')
-rw-r--r--stdlib/source/library/lux/meta/type/primitive.lux105
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))))))))