diff options
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/lux/type/dynamic.lux | 39 |
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)]))))))))) + ) |