aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/library/lux/meta')
-rw-r--r--stdlib/source/library/lux/meta/annotation.lux95
-rw-r--r--stdlib/source/library/lux/meta/location.lux49
2 files changed, 144 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/meta/annotation.lux b/stdlib/source/library/lux/meta/annotation.lux
new file mode 100644
index 000000000..1b7ee480b
--- /dev/null
+++ b/stdlib/source/library/lux/meta/annotation.lux
@@ -0,0 +1,95 @@
+(.module:
+ [library
+ [lux (#- nat int rev)
+ [abstract
+ ["." monad (#+ do)]]
+ [data
+ ["." maybe]
+ ["." name ("#\." equivalence)]]]])
+
+(type: #export Annotation
+ Code)
+
+(def: #export (value tag ann)
+ (-> Name Annotation (Maybe Code))
+ (case ann
+ [_ (#.Record ann)]
+ (loop [ann ann]
+ (case ann
+ (#.Cons [key value] ann')
+ (case key
+ [_ (#.Tag tag')]
+ (if (name\= tag tag')
+ (#.Some value)
+ (recur ann'))
+
+ _
+ (recur ann'))
+
+ #.Nil
+ #.None))
+
+ _
+ #.None))
+
+(template [<name> <tag> <type>]
+ [(def: #export (<name> tag ann)
+ (-> Name Annotation (Maybe <type>))
+ (case (..value tag ann)
+ (#.Some [_ (<tag> value)])
+ (#.Some value)
+
+ _
+ #.None))]
+
+ [bit #.Bit Bit]
+ [nat #.Nat Nat]
+ [int #.Int Int]
+ [rev #.Rev Rev]
+ [frac #.Frac Frac]
+ [text #.Text Text]
+ [identifier #.Identifier Name]
+ [tag #.Tag Name]
+ [form #.Form (List Code)]
+ [tuple #.Tuple (List Code)]
+ [record #.Record (List [Code Code])]
+ )
+
+(def: #export documentation
+ (-> Annotation (Maybe Text))
+ (..text (name_of #.doc)))
+
+(def: #export (flagged? flag)
+ (-> Name Annotation Bit)
+ (|>> (..bit flag) (maybe.default false)))
+
+(template [<name> <tag>]
+ [(def: #export <name>
+ (-> Annotation Bit)
+ (..flagged? (name_of <tag>)))]
+
+ [implementation? #.implementation?]
+ [recursive_type? #.type-rec?]
+ [signature? #.sig?]
+ )
+
+(def: (parse_text input)
+ (-> Code (Maybe Text))
+ (case input
+ [_ (#.Text actual_value)]
+ (#.Some actual_value)
+
+ _
+ #.None))
+
+(template [<name> <tag>]
+ [(def: #export (<name> ann)
+ (-> Annotation (List Text))
+ (maybe.default (list)
+ (do {! maybe.monad}
+ [args (..tuple (name_of <tag>) ann)]
+ (monad.map ! ..parse_text args))))]
+
+ [function_arguments #.func-args]
+ [type_arguments #.type-args]
+ )
diff --git a/stdlib/source/library/lux/meta/location.lux b/stdlib/source/library/lux/meta/location.lux
new file mode 100644
index 000000000..ddc40b147
--- /dev/null
+++ b/stdlib/source/library/lux/meta/location.lux
@@ -0,0 +1,49 @@
+(.module:
+ [library
+ [lux #*
+ [abstract
+ [equivalence (#+ Equivalence)]]]])
+
+(implementation: #export equivalence
+ (Equivalence Location)
+
+ (def: (= reference subject)
+ (and ("lux text =" (get@ #.module reference) (get@ #.module subject))
+ ("lux i64 =" (get@ #.line reference) (get@ #.line subject))
+ ("lux i64 =" (get@ #.column reference) (get@ #.column subject)))))
+
+(def: #export dummy
+ Location
+ {#.module ""
+ #.line 0
+ #.column 0})
+
+(macro: #export (here tokens compiler)
+ (case tokens
+ #.Nil
+ (let [location (get@ #.location compiler)]
+ (#.Right [compiler
+ (list (` [(~ [..dummy (#.Text (get@ #.module location))])
+ (~ [..dummy (#.Nat (get@ #.line location))])
+ (~ [..dummy (#.Nat (get@ #.column location))])]))]))
+
+ _
+ (#.Left (`` (("lux in-module" (~~ (static .prelude_module)) wrong_syntax_error) (name_of ..here))))))
+
+(def: #export (format value)
+ (-> Location Text)
+ (let [separator ","
+ [file line column] value]
+ ($_ "lux text concat"
+ "@"
+ (`` (("lux in-module" (~~ (static .prelude_module)) .text\encode) file)) separator
+ (`` (("lux in-module" (~~ (static .prelude_module)) .nat\encode) line)) separator
+ (`` (("lux in-module" (~~ (static .prelude_module)) .nat\encode) column)))))
+
+(def: \n
+ ("lux i64 char" +10))
+
+(def: #export (with location error)
+ (-> Location Text Text)
+ ($_ "lux text concat" (..format location) \n
+ error))