aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source
diff options
context:
space:
mode:
authorEduardo Julian2019-01-24 00:16:16 -0400
committerEduardo Julian2019-01-24 00:16:16 -0400
commit94f60efe5745accce36c5d6824c71f00a12dd384 (patch)
treeb98a628314830a765b9d791e86a7da4fb81209d3 /stdlib/source
parente115f5f07f5b663b9f533049991a9ab834b44f5e (diff)
Added dynamic typing.
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/type/dynamic.lux39
1 files changed, 39 insertions, 0 deletions
diff --git a/stdlib/source/lux/type/dynamic.lux b/stdlib/source/lux/type/dynamic.lux
new file mode 100644
index 000000000..d57669213
--- /dev/null
+++ b/stdlib/source/lux/type/dynamic.lux
@@ -0,0 +1,39 @@
+(.module:
+ [lux #*
+ [control
+ ["ex" exception (#+ exception:)]]
+ [data
+ ["." error]
+ [text
+ format]]
+ [macro (#+ with-gensyms)
+ ["." syntax (#+ syntax:)]]
+ ["." type
+ abstract]])
+
+(exception: #export (wrong-type {expected Type} {actual Type})
+ (ex.report ["Expected" (%type expected)]
+ ["Actual" (%type actual)]))
+
+(abstract: #export Dynamic
+ {}
+
+ [Type Any]
+
+ (def: dynamic-abstraction (-> [Type Any] Dynamic) (|>> :abstraction))
+ (def: dynamic-representation (-> Dynamic [Type Any]) (|>> :representation))
+
+ (syntax: #export (:dynamic value)
+ (with-gensyms [g!value]
+ (wrap (list (` (let [(~ g!value) (~ value)]
+ ((~! ..dynamic-abstraction) [(:of (~ g!value)) (~ g!value)])))))))
+
+ (syntax: #export (:check type value)
+ (with-gensyms [g!type g!value]
+ (wrap (list (` (let [[(~ g!type) (~ g!value)] ((~! ..dynamic-representation) (~ value))]
+ (: ((~! error.Error) (~ type))
+ (if (:: (~! type.Equivalence<Type>) (~' =)
+ (.type (~ type)) (~ g!type))
+ (#error.Success (:coerce (~ type) (~ g!value)))
+ ((~! ex.throw) ..wrong-type [(.type (~ type)) (~ g!type)])))))))))
+ )