From f8c2389db4a9b3239b00b9d209237d5116e12e3c Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Wed, 25 Jan 2017 07:02:33 -0400 Subject: - Renamed lux/data/struct/tree to lux/data/struct/tree/rose. - Moved lux/data/struct/zipper to lux/data/struct/tree/zipper. - Moved lux/regex to lux/lexer/regex. - Changed the suffix of annotation tags, from M to A. - Renamed Frac(tional) numbers to Deg(rees). --- lux-mode/lux-mode.el | 2 +- luxc/src/lux.clj | 10 +- luxc/src/lux/analyser.clj | 6 +- luxc/src/lux/analyser/base.clj | 2 +- luxc/src/lux/analyser/case.clj | 30 +- luxc/src/lux/analyser/host.clj | 64 +-- luxc/src/lux/analyser/module.clj | 14 +- luxc/src/lux/base.clj | 98 ++--- luxc/src/lux/compiler.clj | 4 +- luxc/src/lux/compiler/cache.clj | 2 +- luxc/src/lux/compiler/cache/ann.clj | 44 +- luxc/src/lux/compiler/case.clj | 2 +- luxc/src/lux/compiler/host.clj | 134 +++---- luxc/src/lux/compiler/lux.clj | 16 +- luxc/src/lux/lexer.clj | 14 +- luxc/src/lux/optimizer.clj | 22 +- luxc/src/lux/parser.clj | 4 +- luxc/src/lux/type.clj | 24 +- luxc/src/lux/type/host.clj | 8 +- stdlib/source/lux.lux | 412 +++++++++---------- stdlib/source/lux/compiler.lux | 30 +- stdlib/source/lux/control/ord.lux | 7 +- stdlib/source/lux/data/format/json.lux | 10 +- stdlib/source/lux/data/number.lux | 34 +- stdlib/source/lux/data/struct/set.lux | 4 +- stdlib/source/lux/data/struct/tree.lux | 60 --- stdlib/source/lux/data/struct/tree/rose.lux | 60 +++ stdlib/source/lux/data/struct/tree/zipper.lux | 197 +++++++++ stdlib/source/lux/data/struct/zipper.lux | 197 --------- stdlib/source/lux/data/text/format.lux | 2 +- stdlib/source/lux/lexer.lux | 2 +- stdlib/source/lux/lexer/regex.lux | 491 +++++++++++++++++++++++ stdlib/source/lux/macro/ast.lux | 6 +- stdlib/source/lux/macro/poly.lux | 4 +- stdlib/source/lux/macro/poly/eq.lux | 2 +- stdlib/source/lux/macro/poly/text-encoder.lux | 2 +- stdlib/source/lux/macro/syntax.lux | 10 +- stdlib/source/lux/macro/syntax/common.lux | 4 +- stdlib/source/lux/math.lux | 6 +- stdlib/source/lux/math/simple.lux | 44 +- stdlib/source/lux/random.lux | 6 +- stdlib/source/lux/regex.lux | 491 ----------------------- stdlib/source/lux/test.lux | 2 +- stdlib/test/test/lux.lux | 18 +- stdlib/test/test/lux/data/number.lux | 18 +- stdlib/test/test/lux/data/struct/tree.lux | 40 -- stdlib/test/test/lux/data/struct/tree/rose.lux | 40 ++ stdlib/test/test/lux/data/struct/tree/zipper.lux | 128 ++++++ stdlib/test/test/lux/data/struct/zipper.lux | 128 ------ stdlib/test/test/lux/lexer/regex.lux | 274 +++++++++++++ stdlib/test/test/lux/macro/syntax.lux | 2 +- stdlib/test/test/lux/math/simple.lux | 4 +- stdlib/test/test/lux/regex.lux | 274 ------------- stdlib/test/tests.lux | 6 +- 54 files changed, 1761 insertions(+), 1754 deletions(-) delete mode 100644 stdlib/source/lux/data/struct/tree.lux create mode 100644 stdlib/source/lux/data/struct/tree/rose.lux create mode 100644 stdlib/source/lux/data/struct/tree/zipper.lux delete mode 100644 stdlib/source/lux/data/struct/zipper.lux create mode 100644 stdlib/source/lux/lexer/regex.lux delete mode 100644 stdlib/source/lux/regex.lux delete mode 100644 stdlib/test/test/lux/data/struct/tree.lux create mode 100644 stdlib/test/test/lux/data/struct/tree/rose.lux create mode 100644 stdlib/test/test/lux/data/struct/tree/zipper.lux delete mode 100644 stdlib/test/test/lux/data/struct/zipper.lux create mode 100644 stdlib/test/test/lux/lexer/regex.lux delete mode 100644 stdlib/test/test/lux/regex.lux diff --git a/lux-mode/lux-mode.el b/lux-mode/lux-mode.el index d471370bf..40980f097 100644 --- a/lux-mode/lux-mode.el +++ b/lux-mode/lux-mode.el @@ -248,7 +248,7 @@ Called by `imenu--generic-function'." ("\\<\\+\\(0\\|[1-9][0-9_]*\\)\\>" 0 font-lock-constant-face) ; Int|Real literals ("\\<-?\\(0\\|[1-9][0-9_]*\\)\\(\\.[0-9_]+\\)?\\>" 0 font-lock-constant-face) - ; Frac literals + ; Deg literals ("\\<\\(\\.[0-9_]+\\)\\>" 0 font-lock-constant-face) ; Tags ("#;[a-zA-Z0-9-\\+_=!@\\$%\\^&\\*<>\.,/\\\\\\|':~\\?]+" 0 font-lock-type-face) diff --git a/luxc/src/lux.clj b/luxc/src/lux.clj index c1e04b9a3..d17f1640d 100644 --- a/luxc/src/lux.clj +++ b/luxc/src/lux.clj @@ -15,7 +15,7 @@ (def unit-separator (str (char 31))) -(defn ^:private process-dirs +(defn ^:private separate-paths "(-> Text (List Text))" [resources-dirs] (-> resources-dirs @@ -26,14 +26,14 @@ (defn -main [& args] (|case (&/->list args) (&/$Cons "release" (&/$Cons program-module (&/$Cons resources-dirs (&/$Cons source-dirs (&/$Cons target-dir (&/$Nil)))))) - (time (&compiler/compile-program &/$Release program-module (process-dirs resources-dirs) (process-dirs source-dirs) target-dir)) + (time (&compiler/compile-program &/$Release program-module (separate-paths resources-dirs) (separate-paths source-dirs) target-dir)) (&/$Cons "debug" (&/$Cons program-module (&/$Cons resources-dirs (&/$Cons source-dirs (&/$Cons target-dir (&/$Nil)))))) - (time (&compiler/compile-program &/$Debug program-module (process-dirs resources-dirs) (process-dirs source-dirs) target-dir)) + (time (&compiler/compile-program &/$Debug program-module (separate-paths resources-dirs) (separate-paths source-dirs) target-dir)) (&/$Cons "repl" (&/$Cons resources-dirs (&/$Cons source-dirs (&/$Cons target-dir (&/$Nil))))) - (&repl/repl (process-dirs resources-dirs) - (process-dirs source-dirs) + (&repl/repl (separate-paths resources-dirs) + (separate-paths source-dirs) target-dir) _ diff --git a/luxc/src/lux/analyser.clj b/luxc/src/lux/analyser.clj index eefa5ee3d..f47bcf914 100644 --- a/luxc/src/lux/analyser.clj +++ b/luxc/src/lux/analyser.clj @@ -79,9 +79,9 @@ (|do [_ (&type/check exo-type &type/Int)] (return (&/|list (&&/|meta exo-type cursor (&&/$int ?value))))) - (&/$FracS ?value) - (|do [_ (&type/check exo-type &type/Frac)] - (return (&/|list (&&/|meta exo-type cursor (&&/$frac ?value))))) + (&/$DegS ?value) + (|do [_ (&type/check exo-type &type/Deg)] + (return (&/|list (&&/|meta exo-type cursor (&&/$deg ?value))))) (&/$RealS ?value) (|do [_ (&type/check exo-type &type/Real)] diff --git a/luxc/src/lux/analyser/base.clj b/luxc/src/lux/analyser/base.clj index 9bdcdeb11..ccc7260bc 100644 --- a/luxc/src/lux/analyser/base.clj +++ b/luxc/src/lux/analyser/base.clj @@ -14,7 +14,7 @@ ("bool" 1) ("nat" 1) ("int" 1) - ("frac" 1) + ("deg" 1) ("real" 1) ("char" 1) ("text" 1) diff --git a/luxc/src/lux/analyser/case.clj b/luxc/src/lux/analyser/case.clj index a5c37ba6b..042ca8352 100644 --- a/luxc/src/lux/analyser/case.clj +++ b/luxc/src/lux/analyser/case.clj @@ -20,7 +20,7 @@ ("BoolTotal" 2) ("NatTotal" 2) ("IntTotal" 2) - ("FracTotal" 2) + ("DegTotal" 2) ("RealTotal" 2) ("CharTotal" 2) ("TextTotal" 2) @@ -33,7 +33,7 @@ ("BoolTestAC" 1) ("NatTestAC" 1) ("IntTestAC" 1) - ("FracTestAC" 1) + ("DegTestAC" 1) ("RealTestAC" 1) ("CharTestAC" 1) ("TextTestAC" 1) @@ -291,10 +291,10 @@ =kont kont] (return (&/T [($IntTestAC ?value) =kont]))) - (&/$FracS ?value) - (|do [_ (&type/check value-type &type/Frac) + (&/$DegS ?value) + (|do [_ (&type/check value-type &type/Deg) =kont kont] - (return (&/T [($FracTestAC ?value) =kont]))) + (return (&/T [($DegTestAC ?value) =kont]))) (&/$RealS ?value) (|do [_ (&type/check value-type &type/Real) @@ -426,8 +426,8 @@ [($IntTotal total? ?values) ($NoTestAC)] (return ($IntTotal true ?values)) - [($FracTotal total? ?values) ($NoTestAC)] - (return ($FracTotal true ?values)) + [($DegTotal total? ?values) ($NoTestAC)] + (return ($DegTotal true ?values)) [($RealTotal total? ?values) ($NoTestAC)] (return ($RealTotal true ?values)) @@ -456,8 +456,8 @@ [($IntTotal total? ?values) ($StoreTestAC ?idx)] (return ($IntTotal true ?values)) - [($FracTotal total? ?values) ($StoreTestAC ?idx)] - (return ($FracTotal true ?values)) + [($DegTotal total? ?values) ($StoreTestAC ?idx)] + (return ($DegTotal true ?values)) [($RealTotal total? ?values) ($StoreTestAC ?idx)] (return ($RealTotal true ?values)) @@ -492,11 +492,11 @@ [($IntTotal total? ?values) ($IntTestAC ?value)] (return ($IntTotal total? (&/$Cons ?value ?values))) - [($DefaultTotal total?) ($FracTestAC ?value)] - (return ($FracTotal total? (&/|list ?value))) + [($DefaultTotal total?) ($DegTestAC ?value)] + (return ($DegTotal total? (&/|list ?value))) - [($FracTotal total? ?values) ($FracTestAC ?value)] - (return ($FracTotal total? (&/$Cons ?value ?values))) + [($DegTotal total? ?values) ($DegTestAC ?value)] + (return ($DegTotal total? (&/$Cons ?value ?values))) [($DefaultTotal total?) ($RealTestAC ?value)] (return ($RealTotal total? (&/|list ?value))) @@ -585,8 +585,8 @@ (|do [_ (&type/check value-type &type/Int)] (return ?total)) - ($FracTotal ?total _) - (|do [_ (&type/check value-type &type/Frac)] + ($DegTotal ?total _) + (|do [_ (&type/check value-type &type/Deg)] (return ?total)) ($RealTotal ?total _) diff --git a/luxc/src/lux/analyser/host.clj b/luxc/src/lux/analyser/host.clj index 977a7b1fe..8c6b1ac80 100644 --- a/luxc/src/lux/analyser/host.clj +++ b/luxc/src/lux/analyser/host.clj @@ -1074,23 +1074,23 @@ ^:private analyse-nat-eq ["nat" "="] &type/Nat &type/Bool ^:private analyse-nat-lt ["nat" "<"] &type/Nat &type/Bool - ^:private analyse-frac-add ["frac" "+"] &type/Frac &type/Frac - ^:private analyse-frac-sub ["frac" "-"] &type/Frac &type/Frac - ^:private analyse-frac-mul ["frac" "*"] &type/Frac &type/Frac - ^:private analyse-frac-div ["frac" "/"] &type/Frac &type/Frac - ^:private analyse-frac-rem ["frac" "%"] &type/Frac &type/Frac - ^:private analyse-frac-eq ["frac" "="] &type/Frac &type/Bool - ^:private analyse-frac-lt ["frac" "<"] &type/Frac &type/Bool + ^:private analyse-deg-add ["deg" "+"] &type/Deg &type/Deg + ^:private analyse-deg-sub ["deg" "-"] &type/Deg &type/Deg + ^:private analyse-deg-mul ["deg" "*"] &type/Deg &type/Deg + ^:private analyse-deg-div ["deg" "/"] &type/Deg &type/Deg + ^:private analyse-deg-rem ["deg" "%"] &type/Deg &type/Deg + ^:private analyse-deg-eq ["deg" "="] &type/Deg &type/Bool + ^:private analyse-deg-lt ["deg" "<"] &type/Deg &type/Bool ) -(defn ^:private analyse-frac-scale [analyse exo-type ?values] +(defn ^:private analyse-deg-scale [analyse exo-type ?values] (|do [:let [(&/$Cons x (&/$Cons y (&/$Nil))) ?values] - =x (&&/analyse-1 analyse &type/Frac x) + =x (&&/analyse-1 analyse &type/Deg x) =y (&&/analyse-1 analyse &type/Nat y) - _ (&type/check exo-type &type/Frac) + _ (&type/check exo-type &type/Deg) _cursor &/cursor] - (return (&/|list (&&/|meta &type/Frac _cursor - (&&/$proc (&/T ["frac" "scale"]) (&/|list =x =y) (&/|list))))))) + (return (&/|list (&&/|meta &type/Deg _cursor + (&&/$proc (&/T ["deg" "scale"]) (&/|list =x =y) (&/|list))))))) (do-template [ ] (do (defn [analyse exo-type ?values] @@ -1111,7 +1111,7 @@ (&&/$proc (&/T ) (&/|list =x) (&/|list))))))))) ^:private analyse-nat-encode ["nat" "encode"] ^:private analyse-nat-decode ["nat" "decode"] &type/Nat - ^:private analyse-frac-encode ["frac" "encode"] ^:private analyse-frac-decode ["frac" "decode"] &type/Frac + ^:private analyse-deg-encode ["deg" "encode"] ^:private analyse-deg-decode ["deg" "decode"] &type/Deg ) (do-template [ ] @@ -1125,8 +1125,8 @@ ^:private analyse-nat-min-value &type/Nat ["nat" "min-value"] ^:private analyse-nat-max-value &type/Nat ["nat" "max-value"] - ^:private analyse-frac-min-value &type/Frac ["frac" "min-value"] - ^:private analyse-frac-max-value &type/Frac ["frac" "max-value"] + ^:private analyse-deg-min-value &type/Deg ["deg" "min-value"] + ^:private analyse-deg-max-value &type/Deg ["deg" "max-value"] ) (do-template [ ] @@ -1143,8 +1143,8 @@ ^:private analyse-int-to-nat &type/Int &type/Nat ["int" "to-nat"] ^:private analyse-char-to-nat &type/Char &type/Nat ["char" "to-nat"] - ^:private analyse-frac-to-real &type/Frac &type/Real ["frac" "to-real"] - ^:private analyse-real-to-frac &type/Real &type/Frac ["real" "to-frac"] + ^:private analyse-deg-to-real &type/Deg &type/Real ["deg" "to-real"] + ^:private analyse-real-to-deg &type/Real &type/Deg ["real" "to-deg"] ) (defn analyse-host [analyse exo-type compilers category proc ?values] @@ -1189,21 +1189,21 @@ "to-char" (analyse-nat-to-char analyse exo-type ?values) ) - "frac" + "deg" (case proc - "+" (analyse-frac-add analyse exo-type ?values) - "-" (analyse-frac-sub analyse exo-type ?values) - "*" (analyse-frac-mul analyse exo-type ?values) - "/" (analyse-frac-div analyse exo-type ?values) - "%" (analyse-frac-rem analyse exo-type ?values) - "=" (analyse-frac-eq analyse exo-type ?values) - "<" (analyse-frac-lt analyse exo-type ?values) - "encode" (analyse-frac-encode analyse exo-type ?values) - "decode" (analyse-frac-decode analyse exo-type ?values) - "min-value" (analyse-frac-min-value analyse exo-type ?values) - "max-value" (analyse-frac-max-value analyse exo-type ?values) - "to-real" (analyse-frac-to-real analyse exo-type ?values) - "scale" (analyse-frac-scale analyse exo-type ?values) + "+" (analyse-deg-add analyse exo-type ?values) + "-" (analyse-deg-sub analyse exo-type ?values) + "*" (analyse-deg-mul analyse exo-type ?values) + "/" (analyse-deg-div analyse exo-type ?values) + "%" (analyse-deg-rem analyse exo-type ?values) + "=" (analyse-deg-eq analyse exo-type ?values) + "<" (analyse-deg-lt analyse exo-type ?values) + "encode" (analyse-deg-encode analyse exo-type ?values) + "decode" (analyse-deg-decode analyse exo-type ?values) + "min-value" (analyse-deg-min-value analyse exo-type ?values) + "max-value" (analyse-deg-max-value analyse exo-type ?values) + "to-real" (analyse-deg-to-real analyse exo-type ?values) + "scale" (analyse-deg-scale analyse exo-type ?values) ) "int" @@ -1213,7 +1213,7 @@ "real" (case proc - "to-frac" (analyse-real-to-frac analyse exo-type ?values) + "to-deg" (analyse-real-to-deg analyse exo-type ?values) ) "char" diff --git a/luxc/src/lux/analyser/module.clj b/luxc/src/lux/analyser/module.clj index 62948bf0d..272f37e64 100644 --- a/luxc/src/lux/analyser/module.clj +++ b/luxc/src/lux/analyser/module.clj @@ -204,14 +204,14 @@ (|let [[?type ?meta ?value] $def] (if (.equals ^Object current-module module) (|case (&meta/meta-get &meta/alias-tag ?meta) - (&/$Some (&/$IdentM [?r-module ?r-name])) + (&/$Some (&/$IdentA [?r-module ?r-name])) ((find-def ?r-module ?r-name) state) _ (return* state (&/T [(&/T [module name]) $def]))) (|case (&meta/meta-get &meta/export?-tag ?meta) - (&/$Some (&/$BoolM true)) + (&/$Some (&/$BoolA true)) (return* state (&/T [(&/T [module name]) $def])) _ @@ -364,7 +364,7 @@ (|let [[k _def-data] kv [_ ?def-meta _] _def-data] (|case (&meta/meta-get &meta/alias-tag ?def-meta) - (&/$Some (&/$IdentM [?r-module ?r-name])) + (&/$Some (&/$IdentA [?r-module ?r-name])) (&/T [k (str ?r-module ";" ?r-name) _def-data]) _ @@ -374,7 +374,7 @@ (do-template [ ] (defn [module name meta type] (|case (&meta/meta-get meta) - (&/$Some (&/$BoolM true)) + (&/$Some (&/$BoolA true)) (&/try-all% (&/|list (&type/check type) (&/fail-with-loc (str "[Analyser Error] Can't tag as lux;" "? if it's not a " ": " (str module ";" name))))) @@ -387,11 +387,11 @@ (defn fetch-imports [meta] (|case (&meta/meta-get &meta/imports-tag meta) - (&/$Some (&/$ListM _parts)) + (&/$Some (&/$ListA _parts)) (&/map% (fn [_part] (|case _part - (&/$ListM (&/$Cons [(&/$TextM _module) - (&/$Cons [(&/$TextM _alias) + (&/$ListA (&/$Cons [(&/$TextA _module) + (&/$Cons [(&/$TextA _alias) (&/$Nil)])])) (return (&/T [_module _alias])) diff --git a/luxc/src/lux/base.clj b/luxc/src/lux/base.clj index 69dbdf5bf..f893f3a02 100644 --- a/luxc/src/lux/base.clj +++ b/luxc/src/lux/base.clj @@ -74,7 +74,7 @@ ("BoolS" 1) ("NatS" 1) ("IntS" 1) - ("FracS" 1) + ("DegS" 1) ("RealS" 1) ("CharS" 1) ("TextS" 1) @@ -216,16 +216,16 @@ ;; Meta-data (defvariant - ("BoolM" 1) - ("NatM" 1) - ("IntM" 1) - ("FracM" 1) - ("RealM" 1) - ("CharM" 1) - ("TextM" 1) - ("IdentM" 1) - ("ListM" 1) - ("DictM" 1)) + ("BoolA" 1) + ("NatA" 1) + ("IntA" 1) + ("DegA" 1) + ("RealA" 1) + ("CharA" 1) + ("TextA" 1) + ("IdentA" 1) + ("ListA" 1) + ("DictA" 1)) ;; [Exports] (def ^:const name-field "_name") @@ -1059,12 +1059,12 @@ (fn [state] (return* state (get$ $cursor state)))) -(def frac-bits 64) +(def deg-bits 64) (let [clean-separators (fn [^String input] (.replaceAll input "_" "")) - frac-text-to-digits (fn [^String input] - (loop [output (vec (repeat frac-bits 0)) + deg-text-to-digits (fn [^String input] + (loop [output (vec (repeat deg-bits 0)) index (dec (.length input))] (if (>= index 0) (let [digit (Byte/parseByte (.substring input index (inc index)))] @@ -1081,50 +1081,50 @@ (int (/ raw 10)) (assoc digits index (rem raw 10)))) digits))) - frac-digit-power (fn [level] - (loop [output (-> (vec (repeat frac-bits 0)) + deg-digit-power (fn [level] + (loop [output (-> (vec (repeat deg-bits 0)) (assoc level 1)) times level] (if (>= times 0) (recur (times5 level output) (dec times)) output))) - frac-digits-lt (fn frac-digits-lt + deg-digits-lt (fn deg-digits-lt ([subject param index] - (and (< index frac-bits) + (and (< index deg-bits) (or (< (get subject index) (get param index)) (and (= (get subject index) (get param index)) - (frac-digits-lt subject param (inc index)))))) + (deg-digits-lt subject param (inc index)))))) ([subject param] - (frac-digits-lt subject param 0))) - frac-digits-sub-once (fn [subject param-digit index] + (deg-digits-lt subject param 0))) + deg-digits-sub-once (fn [subject param-digit index] (if (>= (get subject index) param-digit) (update-in subject [index] #(- % param-digit)) (recur (update-in subject [index] #(- 10 (- param-digit %))) 1 (dec index)))) - frac-digits-sub (fn [subject param] + deg-digits-sub (fn [subject param] (loop [target subject - index (dec frac-bits)] + index (dec deg-bits)] (if (>= index 0) - (recur (frac-digits-sub-once target (get param index) index) + (recur (deg-digits-sub-once target (get param index) index) (dec index)) target))) - frac-digits-to-text (fn [digits] + deg-digits-to-text (fn [digits] (loop [output "" - index (dec frac-bits)] + index (dec deg-bits)] (if (>= index 0) (recur (-> (get digits index) (Character/forDigit 10) (str output)) (dec index)) output))) - add-frac-digit-powers (fn [dl dr] - (loop [index (dec frac-bits) - output (vec (repeat frac-bits 0)) + add-deg-digit-powers (fn [dl dr] + (loop [index (dec deg-bits) + output (vec (repeat deg-bits 0)) carry 0] (if (>= index 0) (let [raw (+ carry @@ -1134,45 +1134,45 @@ (assoc output index (rem raw 10)) (int (/ raw 10)))) output)))] - ;; Based on the LuxRT.encode_frac method - (defn encode-frac [input] + ;; Based on the LuxRT.encode_deg method + (defn encode-deg [input] (if (= 0 input) ".0" - (loop [index (dec frac-bits) - output (vec (repeat frac-bits 0))] + (loop [index (dec deg-bits) + output (vec (repeat deg-bits 0))] (if (>= index 0) (recur (dec index) (if (bit-test input index) - (->> (- (dec frac-bits) index) - frac-digit-power - (add-frac-digit-powers output)) + (->> (- (dec deg-bits) index) + deg-digit-power + (add-deg-digit-powers output)) output)) - (-> output frac-digits-to-text + (-> output deg-digits-to-text (->> (str ".")) (.split "0*$") (aget 0)))))) - ;; Based on the LuxRT.decode_frac method - (defn decode-frac [^String input] + ;; Based on the LuxRT.decode_deg method + (defn decode-deg [^String input] (if (and (.startsWith input ".") - (< (.length input) (inc frac-bits))) + (< (.length input) (inc deg-bits))) (loop [digits-left (-> input (.substring 1) clean-separators - frac-text-to-digits) + deg-text-to-digits) index 0 ouput 0] - (if (< index frac-bits) - (let [power-slice (frac-digit-power index)] - (if (not (frac-digits-lt digits-left power-slice)) - (recur (frac-digits-sub digits-left power-slice) + (if (< index deg-bits) + (let [power-slice (deg-digit-power index)] + (if (not (deg-digits-lt digits-left power-slice)) + (recur (deg-digits-sub digits-left power-slice) (inc index) - (bit-set ouput (- (dec frac-bits) index))) + (bit-set ouput (- (dec deg-bits) index))) (recur digits-left (inc index) ouput))) ouput)) - (throw (str "Bad format for Frac number: " input)))) + (throw (str "Bad format for Deg number: " input)))) ) (defn show-ast [ast] @@ -1186,8 +1186,8 @@ [_ ($IntS ?value)] (pr-str ?value) - [_ ($FracS ?value)] - (encode-frac ?value) + [_ ($DegS ?value)] + (encode-deg ?value) [_ ($RealS ?value)] (pr-str ?value) diff --git a/luxc/src/lux/compiler.clj b/luxc/src/lux/compiler.clj index 48c90e759..0c30c76e9 100644 --- a/luxc/src/lux/compiler.clj +++ b/luxc/src/lux/compiler.clj @@ -60,8 +60,8 @@ (&o/$int ?value) (&&lux/compile-int ?value) - (&o/$frac ?value) - (&&lux/compile-frac ?value) + (&o/$deg ?value) + (&&lux/compile-deg ?value) (&o/$real ?value) (&&lux/compile-real ?value) diff --git a/luxc/src/lux/compiler/cache.clj b/luxc/src/lux/compiler/cache.clj index dbb7945b8..436f778f5 100644 --- a/luxc/src/lux/compiler/cache.clj +++ b/luxc/src/lux/compiler/cache.clj @@ -136,7 +136,7 @@ 2 (let [[_name _alias] parts [_ __module __name] (re-find #"^(.*);(.*)$" _alias) def-class (&&/load-class! loader (str (&host-generics/->class-name __module) "." (&host/def-name __name))) - def-anns (&/|list (&/T [&a-meta/alias-tag (&/$IdentM (&/T [__module __name]))])) + def-anns (&/|list (&/T [&a-meta/alias-tag (&/$IdentA (&/T [__module __name]))])) def-value (get-field &/value-field def-class)] (|do [def-type (&a-module/def-type __module __name)] (&a-module/define module _name def-type def-anns def-value))) diff --git a/luxc/src/lux/compiler/cache/ann.clj b/luxc/src/lux/compiler/cache/ann.clj index 7f343d229..e2df55286 100644 --- a/luxc/src/lux/compiler/cache/ann.clj +++ b/luxc/src/lux/compiler/cache/ann.clj @@ -33,34 +33,34 @@ "(-> Ann-Value Text)" [ann] (|case ann - (&/$BoolM value) + (&/$BoolA value) (str "B" value stop) - (&/$NatM value) + (&/$NatA value) (str "N" value stop) - (&/$IntM value) + (&/$IntA value) (str "I" value stop) - (&/$FracM value) - (str "F" value stop) + (&/$DegA value) + (str "D" value stop) - (&/$RealM value) + (&/$RealA value) (str "R" value stop) - (&/$CharM value) + (&/$CharA value) (str "C" value stop) - (&/$TextM value) + (&/$TextA value) (serialize-text value) - (&/$IdentM ident) + (&/$IdentA ident) (serialize-ident ident) - (&/$ListM elems) + (&/$ListA elems) (str "L" (serialize-seq serialize-ann elems)) - (&/$DictM kvs) + (&/$DictA kvs) (str "D" (serialize-seq (fn [kv] (|let [[k v] kv] (str (serialize-text k) @@ -88,13 +88,13 @@ (let [[value* ^String input*] (.split (.substring input 1) stop 2)] [( ( value*)) input*]))) - ^:private deserialize-bool "B" &/$BoolM Boolean/parseBoolean - ^:private deserialize-nat "N" &/$NatM Long/parseLong - ^:private deserialize-int "I" &/$IntM Long/parseLong - ^:private deserialize-frac "F" &/$FracM Long/parseLong - ^:private deserialize-real "R" &/$RealM Double/parseDouble - ^:private deserialize-char "C" &/$CharM (fn [^String input] (.charAt input 0)) - ^:private deserialize-text "T" &/$TextM identity + ^:private deserialize-bool "B" &/$BoolA Boolean/parseBoolean + ^:private deserialize-nat "N" &/$NatA Long/parseLong + ^:private deserialize-int "I" &/$IntA Long/parseLong + ^:private deserialize-deg "D" &/$DegA Long/parseLong + ^:private deserialize-real "R" &/$RealA Double/parseDouble + ^:private deserialize-char "C" &/$CharA (fn [^String input] (.charAt input 0)) + ^:private deserialize-text "T" &/$TextA identity ) (defn ^:private deserialize-ident* [^String input] @@ -107,7 +107,7 @@ (when (.startsWith input "@") (let [[^String ident* ^String input*] (.split (.substring input 1) stop 2) [_module _name] (.split ident* ident-separator 2)] - [(&/$IdentM (&/T [_module _name])) input*]))) + [(&/$IdentA (&/T [_module _name])) input*]))) (defn ^:private deserialize-seq [deserializer ^String input] (cond (.startsWith input nil-signal) @@ -136,8 +136,8 @@ (.substring input 1))] [( elems) input*]))) - ^:private deserialize-list "L" &/$ListM deserialize-ann - ^:private deserialize-dict "D" &/$DictM deserialize-kv + ^:private deserialize-list "L" &/$ListA deserialize-ann + ^:private deserialize-dict "D" &/$DictA deserialize-kv ) (defn ^:private deserialize-ann @@ -146,7 +146,7 @@ (or (deserialize-bool input) (deserialize-nat input) (deserialize-int input) - (deserialize-frac input) + (deserialize-deg input) (deserialize-real input) (deserialize-char input) (deserialize-text input) diff --git a/luxc/src/lux/compiler/case.clj b/luxc/src/lux/compiler/case.clj index afdcd3eed..416c93622 100644 --- a/luxc/src/lux/compiler/case.clj +++ b/luxc/src/lux/compiler/case.clj @@ -90,7 +90,7 @@ (.visitInsn Opcodes/LCMP) (.visitJumpInsn Opcodes/IFNE $else)) - (&o/$FracPM _value) + (&o/$DegPM _value) (doto writer stack-peek &&/unwrap-long diff --git a/luxc/src/lux/compiler/host.clj b/luxc/src/lux/compiler/host.clj index 5f98bcdb9..10a718093 100644 --- a/luxc/src/lux/compiler/host.clj +++ b/luxc/src/lux/compiler/host.clj @@ -777,9 +777,9 @@ (.visitInsn Opcodes/LCMP) ;; I )) -(defn ^:private compile-LuxRT-frac-methods [^ClassWriter =class] - (|let [frac-bits 64 - _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "mul_frac" "(JJ)J" nil nil) +(defn ^:private compile-LuxRT-deg-methods [^ClassWriter =class] + (|let [deg-bits 64 + _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "mul_deg" "(JJ)J" nil nil) ;; Based on: http://stackoverflow.com/a/31629280/6823464 (.visitCode) ;; Bottom part @@ -810,7 +810,7 @@ (.visitInsn Opcodes/LRETURN) (.visitMaxs 0 0) (.visitEnd)) - _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "div_frac" "(JJ)J" nil nil) + _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "div_deg" "(JJ)J" nil nil) (.visitCode) ;; Based on: http://stackoverflow.com/a/8510587/6823464 (.visitVarInsn Opcodes/LLOAD 0) @@ -821,7 +821,7 @@ (.visitInsn Opcodes/LRETURN) (.visitMaxs 0 0) (.visitEnd)) - _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "frac-to-real" "(J)D" nil nil) + _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg-to-real" "(J)D" nil nil) (.visitCode) ;; Translate high bytes (.visitVarInsn Opcodes/LLOAD 0) high-4b @@ -840,7 +840,7 @@ (.visitInsn Opcodes/DRETURN) (.visitMaxs 0 0) (.visitEnd)) - _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "real-to-frac" "(D)J" nil nil) + _ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "real-to-deg" "(D)J" nil nil) (.visitCode) ;; Drop any excess (.visitVarInsn Opcodes/DLOAD 0) @@ -856,9 +856,9 @@ (.visitInsn Opcodes/DREM) (.visitLdcInsn (double (Math/pow 2 32))) (.visitInsn Opcodes/DMUL) - ;; Turn it into a frac + ;; Turn it into a deg (.visitInsn Opcodes/D2L) - ;; Turn the upper half into frac too + ;; Turn the upper half into deg too swap2 (.visitInsn Opcodes/D2L) ;; Combine both pieces @@ -908,10 +908,10 @@ (.visitEnd))) _ (let [$loop-start (new Label) $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "frac_digit_power" "(I)[B" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digit_power" "(I)[B" nil nil) (.visitCode) ;; Initialize digits array. - (.visitLdcInsn (int frac-bits)) + (.visitLdcInsn (int deg-bits)) (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) ;; {digits} (.visitInsn Opcodes/DUP) (.visitVarInsn Opcodes/ILOAD 0) @@ -945,11 +945,11 @@ (.visitEnd))) _ (let [$loop-start (new Label) $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "add_frac_digit_powers" "([B[B)[B" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "add_deg_digit_powers" "([B[B)[B" nil nil) (.visitCode) - (.visitLdcInsn (int (dec frac-bits))) + (.visitLdcInsn (int (dec deg-bits))) (.visitVarInsn Opcodes/ISTORE 2) ;; Index - (.visitLdcInsn (int frac-bits)) + (.visitLdcInsn (int deg-bits)) (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) (.visitVarInsn Opcodes/ASTORE 3) ;; added_digits (.visitLdcInsn (int 0)) ;; {carry} @@ -996,9 +996,9 @@ (.visitEnd))) _ (let [$loop-start (new Label) $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "frac_digits_to_text" "([B)Ljava/lang/String;" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_to_text" "([B)Ljava/lang/String;" nil nil) (.visitCode) - (.visitLdcInsn (int (dec frac-bits))) + (.visitLdcInsn (int (dec deg-bits))) (.visitVarInsn Opcodes/ISTORE 1) ;; Index (.visitLdcInsn "") ;; {text} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1034,7 +1034,7 @@ $not-set (new Label) $next-iteration (new Label) $normal-path (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "encode_frac" "(J)Ljava/lang/String;" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "encode_deg" "(J)Ljava/lang/String;" nil nil) (.visitCode) ;; A quick corner-case to handle. (.visitVarInsn Opcodes/LLOAD 0) @@ -1045,9 +1045,9 @@ (.visitInsn Opcodes/ARETURN) (.visitLabel $normal-path) ;; Normal case - (.visitLdcInsn (int (dec frac-bits))) + (.visitLdcInsn (int (dec deg-bits))) (.visitVarInsn Opcodes/ISTORE 2) ;; Index - (.visitLdcInsn (int frac-bits)) + (.visitLdcInsn (int deg-bits)) (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) (.visitVarInsn Opcodes/ASTORE 3) ;; digits ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1058,7 +1058,7 @@ (.visitJumpInsn Opcodes/IFGE $do-a-round) ;; Prepare text to return. (.visitVarInsn Opcodes/ALOAD 3) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "frac_digits_to_text" "([B)Ljava/lang/String;") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_to_text" "([B)Ljava/lang/String;") (.visitLdcInsn ".") (.visitInsn Opcodes/SWAP) (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "concat" "(Ljava/lang/String;)Ljava/lang/String;") @@ -1076,12 +1076,12 @@ (.visitVarInsn Opcodes/ILOAD 2) bit-set-64? (.visitJumpInsn Opcodes/IFEQ $next-iteration) - (.visitLdcInsn (int (dec frac-bits))) + (.visitLdcInsn (int (dec deg-bits))) (.visitVarInsn Opcodes/ILOAD 2) (.visitInsn Opcodes/ISUB) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "frac_digit_power" "(I)[B") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digit_power" "(I)[B") (.visitVarInsn Opcodes/ALOAD 3) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "add_frac_digit_powers" "([B[B)[B") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "add_deg_digit_powers" "([B[B)[B") (.visitVarInsn Opcodes/ASTORE 3) (.visitJumpInsn Opcodes/GOTO $next-iteration) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1104,14 +1104,14 @@ $do-a-round (new Label) $not-set (new Label) $next-iteration (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "frac_text_to_digits" "(Ljava/lang/String;)[B" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_text_to_digits" "(Ljava/lang/String;)[B" nil nil) (.visitCode) (.visitVarInsn Opcodes/ALOAD 0) (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") (.visitLdcInsn (int 1)) (.visitInsn Opcodes/ISUB) (.visitVarInsn Opcodes/ISTORE 1) ;; Index - (.visitLdcInsn (int frac-bits)) + (.visitLdcInsn (int deg-bits)) (.visitIntInsn Opcodes/NEWARRAY Opcodes/T_BYTE) (.visitVarInsn Opcodes/ASTORE 2) ;; digits ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1152,7 +1152,7 @@ $is-less-than (new Label) $is-equal (new Label)] ;; [B0 <= [B1 - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "frac_digits_lt" "([B[B)Z" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_lt" "([B[B)Z" nil nil) (.visitCode) (.visitLdcInsn (int 0)) (.visitVarInsn Opcodes/ISTORE 2) ;; Index @@ -1161,7 +1161,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (.visitLabel $loop-start) (.visitVarInsn Opcodes/ILOAD 2) - (.visitLdcInsn (int frac-bits)) + (.visitLdcInsn (int deg-bits)) (.visitJumpInsn Opcodes/IF_ICMPLT $do-a-round) (.visitLdcInsn false) (.visitInsn Opcodes/IRETURN) @@ -1204,7 +1204,7 @@ _ (let [$loop-start (new Label) $do-a-round (new Label) $simple-sub (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "frac_digits_sub_once" "([BBI)[B" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_sub_once" "([BBI)[B" nil nil) (.visitCode) (.visitLabel $loop-start) (.visitVarInsn Opcodes/ALOAD 0) @@ -1252,9 +1252,9 @@ (.visitEnd))) _ (let [$loop-start (new Label) $do-a-round (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "frac_digits_sub" "([B[B)[B" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "deg_digits_sub" "([B[B)[B" nil nil) (.visitCode) - (.visitLdcInsn (int (dec frac-bits))) + (.visitLdcInsn (int (dec deg-bits))) (.visitVarInsn Opcodes/ISTORE 2) ;; Index ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1273,7 +1273,7 @@ (.visitVarInsn Opcodes/ILOAD 2) (.visitInsn Opcodes/BALOAD) ;; {target-digits, param-digit} (.visitVarInsn Opcodes/ILOAD 2) ;; {target-digits, param-digit, idx} - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "frac_digits_sub_once" "([BBI)[B") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_sub_once" "([BBI)[B") (.visitVarInsn Opcodes/ASTORE 0) ;; Update target digits ;; Decrement index (.visitVarInsn Opcodes/ILOAD 2) @@ -1292,7 +1292,7 @@ $skip-power (new Label) $iterate (new Label) $bad-format (new Label)] - (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "decode_frac" "(Ljava/lang/String;)Ljava/lang/Object;" nil nil) + (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "decode_deg" "(Ljava/lang/String;)Ljava/lang/Object;" nil nil) (.visitCode) ;; Check prefix (.visitVarInsn Opcodes/ALOAD 0) @@ -1302,7 +1302,7 @@ ;; Check if size is valid (.visitVarInsn Opcodes/ALOAD 0) (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I") - (.visitLdcInsn (int (inc frac-bits))) ;; It's increased, to account for the prefix . + (.visitLdcInsn (int (inc deg-bits))) ;; It's increased, to account for the prefix . (.visitJumpInsn Opcodes/IF_ICMPGT $bad-format) ;; Initialization (.visitTryCatchBlock $from $to $handler "java/lang/Exception") @@ -1311,7 +1311,7 @@ (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "substring" "(I)Ljava/lang/String;") (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "clean_separators" "(Ljava/lang/String;)Ljava/lang/String;") (.visitLabel $from) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "frac_text_to_digits" "(Ljava/lang/String;)[B") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_text_to_digits" "(Ljava/lang/String;)[B") (.visitLabel $to) (.visitVarInsn Opcodes/ASTORE 0) ;; From test to digits... (.visitLdcInsn (int 0)) @@ -1323,7 +1323,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (.visitLabel $loop-start) (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int frac-bits)) + (.visitLdcInsn (int deg-bits)) (.visitJumpInsn Opcodes/IF_ICMPLT $do-a-round) (.visitVarInsn Opcodes/LLOAD 2) &&/wrap-long @@ -1335,18 +1335,18 @@ (.visitLabel $do-a-round) (.visitVarInsn Opcodes/ALOAD 0) (.visitVarInsn Opcodes/ILOAD 1) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "frac_digit_power" "(I)[B") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digit_power" "(I)[B") (.visitInsn Opcodes/DUP2) - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "frac_digits_lt" "([B[B)Z") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_lt" "([B[B)Z") (.visitJumpInsn Opcodes/IFNE $skip-power) ;; Subtract power - (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "frac_digits_sub" "([B[B)[B") + (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "deg_digits_sub" "([B[B)[B") (.visitVarInsn Opcodes/ASTORE 0) ;; Set bit on output (.visitVarInsn Opcodes/LLOAD 2) (.visitLdcInsn (long 1)) (.visitVarInsn Opcodes/ILOAD 1) - (.visitLdcInsn (int (dec frac-bits))) + (.visitLdcInsn (int (dec deg-bits))) (.visitInsn Opcodes/SWAP) (.visitInsn Opcodes/ISUB) (.visitInsn Opcodes/LSHL) @@ -1760,7 +1760,7 @@ (compile-LuxRT-pm-methods) (compile-LuxRT-adt-methods) (compile-LuxRT-nat-methods) - (compile-LuxRT-frac-methods))]] + (compile-LuxRT-deg-methods))]] (&&/save-class! (second (string/split &&/lux-utils-class #"/")) (.toByteArray (doto =class .visitEnd))))) @@ -2441,10 +2441,10 @@ ^:private compile-nat-sub Opcodes/LSUB "java.lang.Long" "longValue" "()J" &&/wrap-long ^:private compile-nat-mul Opcodes/LMUL "java.lang.Long" "longValue" "()J" &&/wrap-long - ^:private compile-frac-add Opcodes/LADD "java.lang.Long" "longValue" "()J" &&/wrap-long - ^:private compile-frac-sub Opcodes/LSUB "java.lang.Long" "longValue" "()J" &&/wrap-long - ^:private compile-frac-rem Opcodes/LSUB "java.lang.Long" "longValue" "()J" &&/wrap-long - ^:private compile-frac-scale Opcodes/LMUL "java.lang.Long" "longValue" "()J" &&/wrap-long + ^:private compile-deg-add Opcodes/LADD "java.lang.Long" "longValue" "()J" &&/wrap-long + ^:private compile-deg-sub Opcodes/LSUB "java.lang.Long" "longValue" "()J" &&/wrap-long + ^:private compile-deg-rem Opcodes/LSUB "java.lang.Long" "longValue" "()J" &&/wrap-long + ^:private compile-deg-scale Opcodes/LMUL "java.lang.Long" "longValue" "()J" &&/wrap-long ) (do-template [ ] @@ -2497,8 +2497,8 @@ ^:private compile-nat-eq 0 - ^:private compile-frac-eq 0 - ^:private compile-frac-lt -1 + ^:private compile-deg-eq 0 + ^:private compile-deg-lt -1 ) (let [+wrapper-class+ (&host-generics/->bytecode-class-name "java.lang.Long")] @@ -2538,8 +2538,8 @@ ^:private compile-nat-min-value (.visitLdcInsn 0) &&/wrap-long ^:private compile-nat-max-value (.visitLdcInsn -1) &&/wrap-long - ^:private compile-frac-min-value (.visitLdcInsn 0) &&/wrap-long - ^:private compile-frac-max-value (.visitLdcInsn -1) &&/wrap-long + ^:private compile-deg-min-value (.visitLdcInsn 0) &&/wrap-long + ^:private compile-deg-max-value (.visitLdcInsn -1) &&/wrap-long ) (do-template [ ] @@ -2563,7 +2563,7 @@ (return nil))))) ^:private compile-nat-encode "encode_nat" ^:private compile-nat-decode "decode_nat" - ^:private compile-frac-encode "encode_frac" ^:private compile-frac-decode "decode_frac" + ^:private compile-deg-encode "encode_deg" ^:private compile-deg-decode "decode_deg" ) (do-template [ ] @@ -2584,8 +2584,8 @@ &&/wrap-long)]] (return nil))) - ^:private compile-frac-mul "mul_frac" - ^:private compile-frac-div "div_frac" + ^:private compile-deg-mul "mul_deg" + ^:private compile-deg-div "div_deg" ) (do-template [ ] @@ -2600,8 +2600,8 @@ )]] (return nil)))) - ^:private compile-frac-to-real "java.lang.Long" "frac-to-real" "(J)D" &&/unwrap-long &&/wrap-double - ^:private compile-real-to-frac "java.lang.Double" "real-to-frac" "(D)J" &&/unwrap-double &&/wrap-long + ^:private compile-deg-to-real "java.lang.Long" "deg-to-real" "(J)D" &&/unwrap-long &&/wrap-double + ^:private compile-real-to-deg "java.lang.Double" "real-to-deg" "(D)J" &&/unwrap-double &&/wrap-long ) (let [widen (fn [^MethodVisitor *writer*] @@ -2674,21 +2674,21 @@ "to-char" (compile-nat-to-char compile ?values special-args) ) - "frac" + "deg" (case proc-name - "+" (compile-frac-add compile ?values special-args) - "-" (compile-frac-sub compile ?values special-args) - "*" (compile-frac-mul compile ?values special-args) - "/" (compile-frac-div compile ?values special-args) - "%" (compile-frac-rem compile ?values special-args) - "=" (compile-frac-eq compile ?values special-args) - "<" (compile-frac-lt compile ?values special-args) - "encode" (compile-frac-encode compile ?values special-args) - "decode" (compile-frac-decode compile ?values special-args) - "max-value" (compile-frac-max-value compile ?values special-args) - "min-value" (compile-frac-min-value compile ?values special-args) - "to-real" (compile-frac-to-real compile ?values special-args) - "scale" (compile-frac-scale compile ?values special-args) + "+" (compile-deg-add compile ?values special-args) + "-" (compile-deg-sub compile ?values special-args) + "*" (compile-deg-mul compile ?values special-args) + "/" (compile-deg-div compile ?values special-args) + "%" (compile-deg-rem compile ?values special-args) + "=" (compile-deg-eq compile ?values special-args) + "<" (compile-deg-lt compile ?values special-args) + "encode" (compile-deg-encode compile ?values special-args) + "decode" (compile-deg-decode compile ?values special-args) + "max-value" (compile-deg-max-value compile ?values special-args) + "min-value" (compile-deg-min-value compile ?values special-args) + "to-real" (compile-deg-to-real compile ?values special-args) + "scale" (compile-deg-scale compile ?values special-args) ) "int" @@ -2698,7 +2698,7 @@ "real" (case proc-name - "to-frac" (compile-real-to-frac compile ?values special-args) + "to-deg" (compile-real-to-deg compile ?values special-args) ) "char" diff --git a/luxc/src/lux/compiler/lux.clj b/luxc/src/lux/compiler/lux.clj index 3d7c4aa7b..fd4130707 100644 --- a/luxc/src/lux/compiler/lux.clj +++ b/luxc/src/lux/compiler/lux.clj @@ -44,7 +44,7 @@ compile-nat "java/lang/Long" "J" long compile-int "java/lang/Long" "J" long - compile-frac "java/lang/Long" "J" long + compile-deg "java/lang/Long" "J" long compile-real "java/lang/Double" "D" double compile-char "java/lang/Character" "C" char ) @@ -260,7 +260,7 @@ (|do [module-name &/get-module-name class-loader &/loader] (|case (&a-meta/meta-get &a-meta/alias-tag ?meta) - (&/$Some (&/$IdentM [r-module r-name])) + (&/$Some (&/$IdentA [r-module r-name])) (if (= 1 (&/|length ?meta)) (|do [:let [current-class (&host-generics/->class-name (str (&host/->module-class r-module) "/" (&host/def-name r-name))) def-class (&&/load-class! class-loader current-class) @@ -311,7 +311,7 @@ :let [def-class (&&/load-class! class-loader (&host-generics/->class-name current-class)) def-type (&a/expr-type* ?body) is-type? (|case (&a-meta/meta-get &a-meta/type?-tag ?meta) - (&/$Some (&/$BoolM true)) + (&/$Some (&/$BoolA true)) true _ @@ -323,7 +323,7 @@ _ (&/without-repl-closure (&a-module/define module-name ?name def-type def-meta def-value)) _ (|case (&/T [is-type? (&a-meta/meta-get &a-meta/tags-tag def-meta)]) - [true (&/$Some (&/$ListM tags*))] + [true (&/$Some (&/$ListA tags*))] (|do [:let [was-exported? (|case (&a-meta/meta-get &a-meta/export?-tag def-meta) (&/$Some _) true @@ -332,7 +332,7 @@ false)] tags (&/map% (fn [tag*] (|case tag* - (&/$TextM tag) + (&/$TextA tag) (return tag) _ @@ -382,7 +382,7 @@ :let [def-class (&&/load-class! class-loader (&host-generics/->class-name current-class)) def-type (&a/expr-type* ?body) is-type? (|case (&a-meta/meta-get &a-meta/type?-tag ?meta) - (&/$Some (&/$BoolM true)) + (&/$Some (&/$BoolA true)) true _ @@ -394,7 +394,7 @@ _ (&/without-repl-closure (&a-module/define module-name ?name def-type def-meta def-value)) _ (|case (&/T [is-type? (&a-meta/meta-get &a-meta/tags-tag def-meta)]) - [true (&/$Some (&/$ListM tags*))] + [true (&/$Some (&/$ListA tags*))] (|do [:let [was-exported? (|case (&a-meta/meta-get &a-meta/export?-tag def-meta) (&/$Some _) true @@ -403,7 +403,7 @@ false)] tags (&/map% (fn [tag*] (|case tag* - (&/$TextM tag) + (&/$TextA tag) (return tag) _ diff --git a/luxc/src/lux/lexer.clj b/luxc/src/lux/lexer.clj index 819c130f0..9dc77b411 100644 --- a/luxc/src/lux/lexer.clj +++ b/luxc/src/lux/lexer.clj @@ -17,7 +17,7 @@ ("Bool" 1) ("Nat" 1) ("Int" 1) - ("Frac" 1) + ("Deg" 1) ("Real" 1) ("Char" 1) ("Text" 1) @@ -158,7 +158,7 @@ (|do [[meta _ token] (&reader/read-regex )] (return (&/T [meta ( token)])))) - lex-bool $Bool #"^(true|false)" + lex-bool $Bool #"^(true|false)" ) (do-template [ ] @@ -166,10 +166,10 @@ (|do [[meta _ token] (&reader/read-regex )] (return (&/T [meta ( (string/replace token #"_" ""))])))) - lex-nat $Nat #"^\+(0|[1-9][0-9_]*)" - lex-int $Int #"^-?(0|[1-9][0-9_]*)" - lex-frac $Frac #"^(\.[0-9_]+)" - lex-real $Real #"^-?(0\.[0-9_]+|[1-9][0-9_]*\.[0-9_]+)(e-?[1-9][0-9_]*)?" + lex-nat $Nat #"^\+(0|[1-9][0-9_]*)" + lex-int $Int #"^-?(0|[1-9][0-9_]*)" + lex-deg $Deg #"^(\.[0-9_]+)" + lex-real $Real #"^-?(0\.[0-9_]+|[1-9][0-9_]*\.[0-9_]+)(e-?[1-9][0-9_]*)?" ) (def lex-char @@ -245,7 +245,7 @@ lex-bool lex-nat lex-real - lex-frac + lex-deg lex-int lex-char lex-text diff --git a/luxc/src/lux/optimizer.clj b/luxc/src/lux/optimizer.clj index 5c30dc44f..8ce8fc20e 100644 --- a/luxc/src/lux/optimizer.clj +++ b/luxc/src/lux/optimizer.clj @@ -13,7 +13,7 @@ ("bool" 1) ("nat" 1) ("int" 1) - ("frac" 1) + ("deg" 1) ("real" 1) ("char" 1) ("text" 1) @@ -75,8 +75,8 @@ ("NatPM" 1) ;; Compare the CDN with an integer value. ("IntPM" 1) - ;; Compare the CDN with a fractional value. - ("FracPM" 1) + ;; Compare the CDN with a degree value. + ("DegPM" 1) ;; Compare the CDN with a real value. ("RealPM" 1) ;; Compare the CDN with a character value. @@ -192,8 +192,8 @@ (&/|list ($IntPM _value) $PopPM) - (&a-case/$FracTestAC _value) - (&/|list ($FracPM _value) + (&a-case/$DegTestAC _value) + (&/|list ($DegPM _value) $PopPM) (&a-case/$RealTestAC _value) @@ -287,8 +287,8 @@ ($IntPM _value) (str "($IntPM " (pr-str _value) ")") - ($FracPM _value) - (str "($FracPM " (pr-str _value) ")") + ($DegPM _value) + (str "($DegPM " (pr-str _value) ")") ($RealPM _value) (str "($RealPM " (pr-str _value) ")") @@ -351,9 +351,9 @@ ($IntPM _pre-value) ($AltPM pre post)) - [($FracPM _pre-value) ($FracPM _post-value)] + [($DegPM _pre-value) ($DegPM _post-value)] (if (= _pre-value _post-value) - ($FracPM _pre-value) + ($DegPM _pre-value) ($AltPM pre post)) [($RealPM _pre-value) ($RealPM _post-value)] @@ -1079,8 +1079,8 @@ (&a/$int value) (&/T [meta ($int value)]) - (&a/$frac value) - (&/T [meta ($frac value)]) + (&a/$deg value) + (&/T [meta ($deg value)]) (&a/$real value) (&/T [meta ($real value)]) diff --git a/luxc/src/lux/parser.clj b/luxc/src/lux/parser.clj index ceafcd92e..c32528096 100644 --- a/luxc/src/lux/parser.clj +++ b/luxc/src/lux/parser.clj @@ -82,8 +82,8 @@ (&lexer/$Int ?value) (return (&/|list (&/T [meta (&/$IntS (Long/parseLong ?value))]))) - (&lexer/$Frac ?value) - (return (&/|list (&/T [meta (&/$FracS (&/decode-frac ?value))]))) + (&lexer/$Deg ?value) + (return (&/|list (&/T [meta (&/$DegS (&/decode-deg ?value))]))) (&lexer/$Real ?value) (return (&/|list (&/T [meta (&/$RealS (Double/parseDouble ?value))]))) diff --git a/luxc/src/lux/type.clj b/luxc/src/lux/type.clj index ba1dd0d70..099682775 100644 --- a/luxc/src/lux/type.clj +++ b/luxc/src/lux/type.clj @@ -30,7 +30,7 @@ (def Bool (&/$NamedT (&/T ["lux" "Bool"]) (&/$HostT "java.lang.Boolean" &/$Nil))) (def Nat (&/$NamedT (&/T ["lux" "Nat"]) (&/$HostT &&host/nat-data-tag &/$Nil))) -(def Frac (&/$NamedT (&/T ["lux" "Frac"]) (&/$HostT &&host/frac-data-tag &/$Nil))) +(def Deg (&/$NamedT (&/T ["lux" "Deg"]) (&/$HostT &&host/deg-data-tag &/$Nil))) (def Int (&/$NamedT (&/T ["lux" "Int"]) (&/$HostT "java.lang.Long" &/$Nil))) (def Real (&/$NamedT (&/T ["lux" "Real"]) (&/$HostT "java.lang.Double" &/$Nil))) (def Char (&/$NamedT (&/T ["lux" "Char"]) (&/$HostT "java.lang.Character" &/$Nil))) @@ -120,33 +120,33 @@ (let [Ann-Value (&/$AppT (&/$BoundT 0) (&/$BoundT 1))] (&/$AppT (&/$UnivQ empty-env (&/$SumT - ;; BoolM + ;; BoolA Bool (&/$SumT - ;; NatM + ;; NatA Nat (&/$SumT - ;; IntM + ;; IntA Int (&/$SumT - ;; FracM - Frac + ;; DegA + Deg (&/$SumT - ;; RealM + ;; RealA Real (&/$SumT - ;; CharM + ;; CharA Char (&/$SumT - ;; TextM + ;; TextA Text (&/$SumT - ;; IdentM + ;; IdentA Ident (&/$SumT - ;; ListM + ;; ListA (&/$AppT List Ann-Value) - ;; DictM + ;; DictA (&/$AppT List (&/$ProdT Text Ann-Value))))))))))) ) &/$VoidT)))) diff --git a/luxc/src/lux/type/host.clj b/luxc/src/lux/type/host.clj index 462e1aebe..33073fa34 100644 --- a/luxc/src/lux/type/host.clj +++ b/luxc/src/lux/type/host.clj @@ -17,7 +17,7 @@ (def array-data-tag "#Array") (def null-data-tag "#Null") (def nat-data-tag "#Nat") -(def frac-data-tag "#Frac") +(def deg-data-tag "#Deg") ;; [Utils] (defn ^:private trace-lineage* [^Class super-class ^Class sub-class] @@ -262,8 +262,8 @@ (try (cond (or (= "java.lang.Object" e!name) (and (= nat-data-tag e!name) (= nat-data-tag a!name)) - (and (= frac-data-tag e!name) - (= frac-data-tag a!name)) + (and (= deg-data-tag e!name) + (= deg-data-tag a!name)) (and (= null-data-tag e!name) (= null-data-tag a!name)) (and (not (primitive-type? e!name)) @@ -273,7 +273,7 @@ (or (and (= array-data-tag e!name) (not= array-data-tag a!name)) (= nat-data-tag e!name) (= nat-data-tag a!name) - (= frac-data-tag e!name) (= frac-data-tag a!name) + (= deg-data-tag e!name) (= deg-data-tag a!name) (= null-data-tag e!name) (= null-data-tag a!name)) (check-error "" (&/$HostT e!name e!params) (&/$HostT a!name a!params)) diff --git a/stdlib/source/lux.lux b/stdlib/source/lux.lux index 76093eb29..bb53b987e 100644 --- a/stdlib/source/lux.lux +++ b/stdlib/source/lux.lux @@ -38,9 +38,9 @@ (+1 [["lux" "doc"] (+6 "Your standard, run-of-the-mill floating-point numbers.")] (+0))))) -(_lux_def Frac - (+12 ["lux" "Frac"] - (+0 "#Frac" (+0))) +(_lux_def Deg + (+12 ["lux" "Deg"] + (+0 "#Deg" (+0))) (+1 [["lux" "type?"] (+0 true)] (+1 [["lux" "export?"] (+0 true)] (+1 [["lux" "doc"] (+6 "Fractional numbers that live in the interval [0,1). @@ -221,56 +221,56 @@ #Nil)))) ## (type: #rec Ann-Value -## (#BoolM Bool) -## (#NatM Nat) -## (#IntM Int) -## (#FracM Frac) -## (#RealM Real) -## (#CharM Char) -## (#TextM Text) -## (#IdentM Ident) -## (#ListM (List Ann-Value)) -## (#DictM (List [Text Ann-Value]))) +## (#BoolA Bool) +## (#NatA Nat) +## (#IntA Int) +## (#DegA Deg) +## (#RealA Real) +## (#CharA Char) +## (#TextA Text) +## (#IdentA Ident) +## (#ListA (List Ann-Value)) +## (#DictA (List [Text Ann-Value]))) (_lux_def Ann-Value (#NamedT ["lux" "Ann-Value"] (_lux_case (#AppT (#BoundT +0) (#BoundT +1)) Ann-Value (#AppT (#UnivQ #Nil - (#SumT ## #BoolM + (#SumT ## #BoolA Bool - (#SumT ## #NatM + (#SumT ## #NatA Nat - (#SumT ## #IntM + (#SumT ## #IntA Int - (#SumT ## #FracM - Frac - (#SumT ## #RealM + (#SumT ## #DegA + Deg + (#SumT ## #RealA Real - (#SumT ## #CharM + (#SumT ## #CharA Char - (#SumT ## #TextM + (#SumT ## #TextA Text - (#SumT ## #IdentM + (#SumT ## #IdentA Ident - (#SumT ## #ListM + (#SumT ## #ListA (#AppT List Ann-Value) - ## #DictM + ## #DictA (#AppT List (#ProdT Text Ann-Value))))))))))) ) Void) )) (#Cons [["lux" "type?"] (+0 true)] (#Cons [["lux" "export?"] (+0 true)] - (#Cons [["lux" "tags"] (+8 (#Cons (+6 "BoolM") - (#Cons (+6 "NatM") - (#Cons (+6 "IntM") - (#Cons (+6 "FracM") - (#Cons (+6 "RealM") - (#Cons (+6 "CharM") - (#Cons (+6 "TextM") - (#Cons (+6 "IdentM") - (#Cons (+6 "ListM") - (#Cons (+6 "DictM") + (#Cons [["lux" "tags"] (+8 (#Cons (+6 "BoolA") + (#Cons (+6 "NatA") + (#Cons (+6 "IntA") + (#Cons (+6 "DegA") + (#Cons (+6 "RealA") + (#Cons (+6 "CharA") + (#Cons (+6 "TextA") + (#Cons (+6 "IdentA") + (#Cons (+6 "ListA") + (#Cons (+6 "DictA") #Nil)))))))))))] (#Cons [["lux" "type-rec?"] (+0 true)] (#Cons [["lux" "doc"] (+6 "The value of an individual annotation.")] @@ -281,21 +281,21 @@ (_lux_def Anns (#NamedT ["lux" "Anns"] (#AppT List (#ProdT Ident Ann-Value))) - (#Cons [["lux" "type?"] (#BoolM true)] - (#Cons [["lux" "export?"] (#BoolM true)] - (#Cons [["lux" "doc"] (#TextM "A set of annotations associated with a definition.")] + (#Cons [["lux" "type?"] (#BoolA true)] + (#Cons [["lux" "export?"] (#BoolA true)] + (#Cons [["lux" "doc"] (#TextA "A set of annotations associated with a definition.")] #Nil)))) (_lux_def default-def-meta-exported (_lux_: Anns - (#Cons [["lux" "type?"] (#BoolM true)] - (#Cons [["lux" "export?"] (#BoolM true)] + (#Cons [["lux" "type?"] (#BoolA true)] + (#Cons [["lux" "export?"] (#BoolA true)] #Nil))) #Nil) (_lux_def default-def-meta-unexported (_lux_: Anns - (#Cons [["lux" "type?"] (#BoolM true)] + (#Cons [["lux" "type?"] (#BoolA true)] #Nil)) #Nil) @@ -304,7 +304,7 @@ (_lux_def Def (#NamedT ["lux" "Def"] (#ProdT Type (#ProdT Anns Void))) - (#Cons [["lux" "doc"] (#TextM "Represents all the data associated with a definition: its type, its annotations, and its value.")] + (#Cons [["lux" "doc"] (#TextA "Represents all the data associated with a definition: its type, its annotations, and its value.")] default-def-meta-exported)) ## (type: (Bindings k v) @@ -320,10 +320,10 @@ (#AppT List (#ProdT (#BoundT +3) (#BoundT +1))))))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "counter") - (#Cons (#TextM "mappings") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "counter") + (#Cons (#TextA "mappings") #Nil)))] - (#Cons [["lux" "type-args"] (#ListM (#Cons (#TextM "k") (#Cons (#TextM "v") #;Nil)))] + (#Cons [["lux" "type-args"] (#ListA (#Cons (#TextA "k") (#Cons (#TextA "v") #;Nil)))] default-def-meta-exported))) ## (type: Cursor @@ -333,11 +333,11 @@ (_lux_def Cursor (#NamedT ["lux" "Cursor"] (#ProdT Text (#ProdT Int Int))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "module") - (#Cons (#TextM "line") - (#Cons (#TextM "column") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "module") + (#Cons (#TextA "line") + (#Cons (#TextA "column") #Nil))))] - (#Cons [["lux" "doc"] (#TextM "Cursors are for specifying the location of AST nodes in Lux files during compilation.")] + (#Cons [["lux" "doc"] (#TextA "Cursors are for specifying the location of AST nodes in Lux files during compilation.")] default-def-meta-exported))) ## (type: (Meta m v) @@ -349,11 +349,11 @@ (#UnivQ #Nil (#ProdT (#BoundT +3) (#BoundT +1))))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "meta") - (#Cons (#TextM "datum") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "meta") + (#Cons (#TextA "datum") #Nil)))] - (#Cons [["lux" "doc"] (#TextM "The type of things that can have meta-data of arbitrary types.")] - (#Cons [["lux" "type-args"] (#ListM (#Cons (#TextM "m") (#Cons (#TextM "v") #;Nil)))] + (#Cons [["lux" "doc"] (#TextA "The type of things that can have meta-data of arbitrary types.")] + (#Cons [["lux" "type-args"] (#ListA (#Cons (#TextA "m") (#Cons (#TextA "v") #;Nil)))] default-def-meta-exported)))) (_lux_def Analysis @@ -378,10 +378,10 @@ (#AppT (#AppT Bindings Text) Analysis) ## "lux;closure" (#AppT (#AppT Bindings Text) Analysis))))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "name") - (#Cons (#TextM "inner-closures") - (#Cons (#TextM "locals") - (#Cons (#TextM "closure") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "name") + (#Cons (#TextA "inner-closures") + (#Cons (#TextA "locals") + (#Cons (#TextA "closure") #Nil)))))] default-def-meta-exported)) @@ -389,7 +389,7 @@ ## (#BoolS Bool) ## (#NatS Nat) ## (#IntS Int) -## (#FracS Frac) +## (#DegS Deg) ## (#RealS Real) ## (#CharS Char) ## (#TextS Text) @@ -413,8 +413,8 @@ Nat (#SumT ## "lux;IntS" Int - (#SumT ## "lux;FracS" - Frac + (#SumT ## "lux;DegS" + Deg (#SumT ## "lux;RealS" Real (#SumT ## "lux;CharS" @@ -433,20 +433,20 @@ (#AppT List (#ProdT AST AST)) ))))))))))) )))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "BoolS") - (#Cons (#TextM "NatS") - (#Cons (#TextM "IntS") - (#Cons (#TextM "FracS") - (#Cons (#TextM "RealS") - (#Cons (#TextM "CharS") - (#Cons (#TextM "TextS") - (#Cons (#TextM "SymbolS") - (#Cons (#TextM "TagS") - (#Cons (#TextM "FormS") - (#Cons (#TextM "TupleS") - (#Cons (#TextM "RecordS") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "BoolS") + (#Cons (#TextA "NatS") + (#Cons (#TextA "IntS") + (#Cons (#TextA "DegS") + (#Cons (#TextA "RealS") + (#Cons (#TextA "CharS") + (#Cons (#TextA "TextS") + (#Cons (#TextA "SymbolS") + (#Cons (#TextA "TagS") + (#Cons (#TextA "FormS") + (#Cons (#TextA "TupleS") + (#Cons (#TextA "RecordS") #Nil)))))))))))))] - (#Cons [["lux" "type-args"] (#ListM (#Cons (#TextM "w") #;Nil))] + (#Cons [["lux" "type-args"] (#ListA (#Cons (#TextA "w") #;Nil))] default-def-meta-exported))) ## (type: AST @@ -456,7 +456,7 @@ (_lux_case (#AppT Meta Cursor) w (#AppT w (#AppT AST' w)))) - (#Cons [["lux" "doc"] (#TextM "The type of AST nodes for Lux syntax.")] + (#Cons [["lux" "doc"] (#TextA "The type of AST nodes for Lux syntax.")] default-def-meta-exported)) (_lux_def ASTList @@ -474,11 +474,11 @@ (#BoundT +3) ## "lux;Right" (#BoundT +1))))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "Left") - (#Cons (#TextM "Right") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "Left") + (#Cons (#TextA "Right") #Nil)))] - (#Cons [["lux" "type-args"] (#ListM (#Cons (#TextM "l") (#Cons (#TextM "r") #;Nil)))] - (#Cons [["lux" "doc"] (#TextM "A choice between two values of different types.")] + (#Cons [["lux" "type-args"] (#ListA (#Cons (#TextA "l") (#Cons (#TextA "r") #;Nil)))] + (#Cons [["lux" "doc"] (#TextA "A choice between two values of different types.")] default-def-meta-exported)))) ## (type: Source @@ -526,15 +526,15 @@ ## "lux;module-anns" Anns) )))))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "module-hash") - (#Cons (#TextM "module-aliases") - (#Cons (#TextM "defs") - (#Cons (#TextM "imports") - (#Cons (#TextM "tags") - (#Cons (#TextM "types") - (#Cons (#TextM "module-anns") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "module-hash") + (#Cons (#TextA "module-aliases") + (#Cons (#TextA "defs") + (#Cons (#TextA "imports") + (#Cons (#TextA "tags") + (#Cons (#TextA "types") + (#Cons (#TextA "module-anns") #Nil))))))))] - (#Cons [["lux" "doc"] (#TextM "All the information contained within a Lux module.")] + (#Cons [["lux" "doc"] (#TextA "All the information contained within a Lux module.")] default-def-meta-exported))) ## (type: Compiler-Mode @@ -552,12 +552,12 @@ #UnitT ## "lux;REPL" #UnitT)))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "Release") - (#Cons (#TextM "Debug") - (#Cons (#TextM "Eval") - (#Cons (#TextM "REPL") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "Release") + (#Cons (#TextA "Debug") + (#Cons (#TextA "Eval") + (#Cons (#TextA "REPL") #Nil)))))] - (#Cons [["lux" "doc"] (#TextM "A sign that shows the conditions under which the compiler is running.")] + (#Cons [["lux" "doc"] (#TextA "A sign that shows the conditions under which the compiler is running.")] default-def-meta-exported))) ## (type: Compiler-Info @@ -572,11 +572,11 @@ Text ## "lux;compiler-mode" Compiler-Mode))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "compiler-name") - (#Cons (#TextM "compiler-version") - (#Cons (#TextM "compiler-mode") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "compiler-name") + (#Cons (#TextA "compiler-version") + (#Cons (#TextA "compiler-mode") #Nil))))] - (#Cons [["lux" "doc"] (#TextM "Information about the current version and type of compiler that is running.")] + (#Cons [["lux" "doc"] (#TextA "Information about the current version and type of compiler that is running.")] default-def-meta-exported))) ## (type: Compiler @@ -613,18 +613,18 @@ (#AppT List Nat) ## "lux;host" Void)))))))))) - (#Cons [["lux" "tags"] (#ListM (#Cons (#TextM "info") - (#Cons (#TextM "source") - (#Cons (#TextM "cursor") - (#Cons (#TextM "modules") - (#Cons (#TextM "scopes") - (#Cons (#TextM "type-vars") - (#Cons (#TextM "expected") - (#Cons (#TextM "seed") - (#Cons (#TextM "scope-type-vars") - (#Cons (#TextM "host") + (#Cons [["lux" "tags"] (#ListA (#Cons (#TextA "info") + (#Cons (#TextA "source") + (#Cons (#TextA "cursor") + (#Cons (#TextA "modules") + (#Cons (#TextA "scopes") + (#Cons (#TextA "type-vars") + (#Cons (#TextA "expected") + (#Cons (#TextA "seed") + (#Cons (#TextA "scope-type-vars") + (#Cons (#TextA "host") #Nil)))))))))))] - (#Cons [["lux" "doc"] (#TextM "Represents the state of the Lux compiler during a run. + (#Cons [["lux" "doc"] (#TextA "Represents the state of the Lux compiler during a run. It is provided to macros during their invocation, so they can access compiler data. @@ -639,10 +639,10 @@ (#LambdaT Compiler (#AppT (#AppT Either Text) (#ProdT Compiler (#BoundT +1)))))) - (#Cons [["lux" "doc"] (#TextM "Computations that can have access to the state of the compiler. + (#Cons [["lux" "doc"] (#TextA "Computations that can have access to the state of the compiler. These computations may fail, or modify the state of the compiler.")] - (#Cons [["lux" "type-args"] (#ListM (#Cons (#TextM "a") #;Nil))] + (#Cons [["lux" "type-args"] (#ListA (#Cons (#TextA "a") #;Nil))] default-def-meta-exported))) ## (type: Macro @@ -650,7 +650,7 @@ (_lux_def Macro (#NamedT ["lux" "Macro"] (#LambdaT ASTList (#AppT Lux ASTList))) - (#Cons [["lux" "doc"] (#TextM "Functions that run at compile-time and allow you to transform and extend the language in powerful ways.")] + (#Cons [["lux" "doc"] (#TextA "Functions that run at compile-time and allow you to transform and extend the language in powerful ways.")] default-def-meta-exported)) ## Base functions & macros @@ -721,9 +721,9 @@ (_lux_lambda _ value (_meta (#IntS value)))) #Nil) -(_lux_def frac$ - (_lux_: (#LambdaT Frac AST) - (_lux_lambda _ value (_meta (#FracS value)))) +(_lux_def deg$ + (_lux_: (#LambdaT Deg AST) + (_lux_lambda _ value (_meta (#DegS value)))) #Nil) (_lux_def real$ @@ -768,7 +768,7 @@ (_lux_def default-macro-meta (_lux_: Anns - (#Cons [["lux" "macro?"] (#BoolM true)] + (#Cons [["lux" "macro?"] (#BoolA true)] #Nil)) #Nil) @@ -826,7 +826,7 @@ (_lux_def export?-meta (_lux_: AST (tuple$ (#Cons [(tuple$ (#Cons [(text$ "lux") (#Cons [(text$ "export?") #Nil])])) - (#Cons [(form$ (#Cons [(tag$ ["lux" "BoolM"]) + (#Cons [(form$ (#Cons [(tag$ ["lux" "BoolA"]) (#Cons [(bool$ true) #Nil])])) #Nil])]))) @@ -835,7 +835,7 @@ (_lux_def hidden?-meta (_lux_: AST (tuple$ (#Cons [(tuple$ (#Cons [(text$ "lux") (#Cons [(text$ "hidden?") #Nil])])) - (#Cons [(form$ (#Cons [(tag$ ["lux" "BoolM"]) + (#Cons [(form$ (#Cons [(tag$ ["lux" "BoolA"]) (#Cons [(bool$ true) #Nil])])) #Nil])]))) @@ -844,7 +844,7 @@ (_lux_def macro?-meta (_lux_: AST (tuple$ (#Cons [(tuple$ (#Cons [(text$ "lux") (#Cons [(text$ "macro?") #Nil])])) - (#Cons [(form$ (#Cons [(tag$ ["lux" "BoolM"]) + (#Cons [(form$ (#Cons [(tag$ ["lux" "BoolA"]) (#Cons [(bool$ true) #Nil])])) #Nil])]))) @@ -972,7 +972,7 @@ (fail "Wrong syntax for macro:'"))) (macro:' #export (comment tokens) - (#Cons [["lux" "doc"] (#TextM "## Throws away any code given to it. + (#Cons [["lux" "doc"] (#TextA "## Throws away any code given to it. ## Great for commenting-out code, while retaining syntax high-lighting and formatting in your text editor. (comment 1 2 3 4)")] #;Nil) @@ -1141,7 +1141,7 @@ (fold (lambda'' [_ acc] (_lux_proc ["jvm" "ladd"] [1 acc])) 0 list)) (macro:' #export (All tokens) - (#Cons [["lux" "doc"] (#TextM "## Universal quantification. + (#Cons [["lux" "doc"] (#TextA "## Universal quantification. (All [a] (-> a a)) @@ -1190,7 +1190,7 @@ )) (macro:' #export (Ex tokens) - (#Cons [["lux" "doc"] (#TextM "## Existential quantification. + (#Cons [["lux" "doc"] (#TextA "## Existential quantification. (Ex [a] [(Codec Text a) a]) @@ -1248,7 +1248,7 @@ list)) (macro:' #export (-> tokens) - (#Cons [["lux" "doc"] (#TextM "## Function types: + (#Cons [["lux" "doc"] (#TextA "## Function types: (-> Int Int Int) ## This is the type of a function that takes 2 Ints and returns an Int.")] @@ -1265,7 +1265,7 @@ (fail "Wrong syntax for ->"))) (macro:' #export (list xs) - (#Cons [["lux" "doc"] (#TextM "## List-construction macro. + (#Cons [["lux" "doc"] (#TextA "## List-construction macro. (list 1 2 3)")] #;Nil) (return (#Cons (fold (lambda'' [head tail] @@ -1277,7 +1277,7 @@ #Nil))) (macro:' #export (list& xs) - (#Cons [["lux" "doc"] (#TextM "## List-construction macro, with the last element being a tail-list. + (#Cons [["lux" "doc"] (#TextA "## List-construction macro, with the last element being a tail-list. ## In other words, this macro prepends elements to another list. (list& 1 2 3 (list 4 5 6))")] #;Nil) @@ -1293,7 +1293,7 @@ (fail "Wrong syntax for list&"))) (macro:' #export (& tokens) - (#Cons [["lux" "doc"] (#TextM "## Tuple types: + (#Cons [["lux" "doc"] (#TextA "## Tuple types: (& Text Int Bool) ## The empty tuple, a.k.a. Unit. @@ -1310,7 +1310,7 @@ )) (macro:' #export (| tokens) - (#Cons [["lux" "doc"] (#TextM "## Variant types: + (#Cons [["lux" "doc"] (#TextA "## Variant types: (| Text Int Bool) ## The empty tuple, a.k.a. Void. @@ -1474,7 +1474,7 @@ ys)) (def:''' #export (splice-helper xs ys) - (#Cons [["lux" "hidden?"] (#BoolM true)] + (#Cons [["lux" "hidden?"] (#BoolA true)] #;Nil) (-> ($' List AST) ($' List AST) ($' List AST)) (_lux_case xs @@ -1485,7 +1485,7 @@ ys)) (macro:' #export (_$ tokens) - (#Cons [["lux" "doc"] (#TextM "## Left-association for the application of binary functions over variadic arguments. + (#Cons [["lux" "doc"] (#TextA "## Left-association for the application of binary functions over variadic arguments. (_$ Text/append \"Hello, \" name \".\\nHow are you?\") ## => @@ -1506,7 +1506,7 @@ (fail "Wrong syntax for _$"))) (macro:' #export ($_ tokens) - (#Cons [["lux" "doc"] (#TextM "## Right-association for the application of binary functions over variadic arguments. + (#Cons [["lux" "doc"] (#TextA "## Right-association for the application of binary functions over variadic arguments. ($_ Text/append \"Hello, \" name \".\\nHow are you?\") ## => @@ -1532,7 +1532,7 @@ ## (: (All [a b] (-> (-> a (m b)) (m a) (m b))) ## bind)) (def:''' Monad - (list& [["lux" "tags"] (#ListM (list (#TextM "wrap") (#TextM "bind")))] + (list& [["lux" "tags"] (#ListA (list (#TextA "wrap") (#TextA "bind")))] default-def-meta-unexported) Type (#NamedT ["lux" "Monad"] @@ -1621,7 +1621,7 @@ ))) (macro:' #export (if tokens) - (list [["lux" "doc"] (#TextM "Picks which expression to evaluate based on a boolean test value. + (list [["lux" "doc"] (#TextA "Picks which expression to evaluate based on a boolean test value. (if true \"Oh, yeah!\" @@ -1706,7 +1706,7 @@ (_lux_case (get name defs) (#Some [def-type def-meta def-value]) (_lux_case (get-meta ["lux" "alias"] def-meta) - (#Some (#IdentM real-name)) + (#Some (#IdentA real-name)) (#Right [state real-name]) _ @@ -1768,8 +1768,8 @@ [_ [_ (#IntS value)]] (return (wrap-meta (form$ (list (tag$ ["lux" "IntS"]) (int$ value))))) - [_ [_ (#FracS value)]] - (return (wrap-meta (form$ (list (tag$ ["lux" "FracS"]) (frac$ value))))) + [_ [_ (#DegS value)]] + (return (wrap-meta (form$ (list (tag$ ["lux" "DegS"]) (deg$ value))))) [_ [_ (#RealS value)]] (return (wrap-meta (form$ (list (tag$ ["lux" "RealS"]) (real$ value))))) @@ -1838,7 +1838,7 @@ )) (macro:' #export (host tokens) - (list [["lux" "doc"] (#TextM "## Macro to treat host-types as Lux-types. + (list [["lux" "doc"] (#TextA "## Macro to treat host-types as Lux-types. (host java.lang.Object) (host java.util.List [java.lang.Long])")]) @@ -1869,7 +1869,7 @@ ))) (macro:' #export (` tokens) - (list [["lux" "doc"] (#TextM "## Hygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~@) must also be used as forms. + (list [["lux" "doc"] (#TextA "## Hygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~@) must also be used as forms. ## All unprefixed macros will receive their parent module's prefix if imported; otherwise will receive the prefix of the module on which the quasi-quote is being used. (` (def: (~ name) (lambda [(~@ args)] @@ -1885,7 +1885,7 @@ (fail "Wrong syntax for `"))) (macro:' #export (`' tokens) - (list [["lux" "doc"] (#TextM "## Unhygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~@) must also be used as forms. + (list [["lux" "doc"] (#TextA "## Unhygienic quasi-quotation as a macro. Unquote (~) and unquote-splice (~@) must also be used as forms. (`' (def: (~ name) (lambda [(~@ args)] (~ body))))")]) @@ -1899,7 +1899,7 @@ (fail "Wrong syntax for `"))) (macro:' #export (' tokens) - (list [["lux" "doc"] (#TextM "## Quotation as a macro. + (list [["lux" "doc"] (#TextA "## Quotation as a macro. (' \"YOLO\")")]) (_lux_case tokens (#Cons template #Nil) @@ -1911,7 +1911,7 @@ (fail "Wrong syntax for '"))) (macro:' #export (|> tokens) - (list [["lux" "doc"] (#TextM "## Piping macro. + (list [["lux" "doc"] (#TextA "## Piping macro. (|> elems (map ->Text) (interpose \" \") (fold Text/append \"\")) ## => @@ -1938,7 +1938,7 @@ (fail "Wrong syntax for |>"))) (macro:' #export (<| tokens) - (list [["lux" "doc"] (#TextM "## Reverse piping macro. + (list [["lux" "doc"] (#TextA "## Reverse piping macro. (<| (fold Text/append \"\") (interpose \" \") (map ->Text) elems) ## => @@ -1965,7 +1965,7 @@ (fail "Wrong syntax for <|"))) (def:''' #export (. f g) - (list [["lux" "doc"] (#TextM "Function composition.")]) + (list [["lux" "doc"] (#TextA "Function composition.")]) (All [a b c] (-> (-> b c) (-> a b) (-> a c))) (lambda' [x] (f (g x)))) @@ -2066,7 +2066,7 @@ (_lux_proc ["jvm" "invokevirtual:java.lang.Object:toString:"] [x])) (macro:' #export (do-template tokens) - (list [["lux" "doc"] (#TextM "## By specifying a pattern (with holes), and the input data to fill those holes, repeats the pattern as many times as necessary. + (list [["lux" "doc"] (#TextA "## By specifying a pattern (with holes), and the input data to fill those holes, repeats the pattern as many times as necessary. (do-template [ ] [(def: #export (-> Int Int) @@ -2097,29 +2097,29 @@ (do-template [ <=-name> <=> <<-doc> <<=-doc> <>-doc> <>=-doc>] [(def:''' #export (<=-name> test subject) - (list [["lux" "doc"] (#TextM )]) + (list [["lux" "doc"] (#TextA )]) (-> Bool) (_lux_proc [ <=>] [subject test])) (def:''' #export ( test subject) - (list [["lux" "doc"] (#TextM <<-doc>)]) + (list [["lux" "doc"] (#TextA <<-doc>)]) (-> Bool) (_lux_proc [ ] [subject test])) (def:''' #export ( test subject) - (list [["lux" "doc"] (#TextM <<=-doc>)]) + (list [["lux" "doc"] (#TextA <<=-doc>)]) (-> Bool) (if (_lux_proc [ ] [subject test]) true (_lux_proc [ <=>] [subject test]))) (def:''' #export ( test subject) - (list [["lux" "doc"] (#TextM <>-doc>)]) + (list [["lux" "doc"] (#TextA <>-doc>)]) (-> Bool) (_lux_proc [ ] [test subject])) (def:''' #export ( test subject) - (list [["lux" "doc"] (#TextM <>=-doc>)]) + (list [["lux" "doc"] (#TextA <>=-doc>)]) (-> Bool) (if (_lux_proc [ ] [test subject]) true @@ -2131,8 +2131,8 @@ [ Int "jvm" i.= "leq" i.< i.<= "llt" i.> i.>= "Integer equality." "Integer less-than." "Integer less-than-equal." "Integer greater-than." "Integer greater-than-equal."] - [Frac "frac" f.= "=" f.< f.<= "<" f.> f.>= - "Fractional equality." "Fractional less-than." "Fractional less-than-equal." "Fractional greater-than." "Fractional greater-than-equal."] + [Deg "deg" d.= "=" d.< d.<= "<" d.> d.>= + "Degree equality." "Degree less-than." "Degree less-than-equal." "Degree greater-than." "Degree greater-than-equal."] [Real "jvm" r.= "deq" r.< r.<= "dlt" r.> r.>= "Real equality." "Real less-than." "Real less-than-equal." "Real greater-than." "Real greater-than-equal."] @@ -2140,7 +2140,7 @@ (do-template [ ] [(def:''' #export ( param subject) - (list [["lux" "doc"] (#TextM )]) + (list [["lux" "doc"] (#TextA )]) (-> ) (_lux_proc [subject param]))] @@ -2156,11 +2156,11 @@ [ Int i./ ["jvm" "ldiv"] "Int(eger) division."] [ Int i.% ["jvm" "lrem"] "Int(eger) remainder."] - [Frac f.+ ["frac" "+"] "Frac(tional) addition."] - [Frac f.- ["frac" "-"] "Frac(tional) substraction."] - [Frac f.* ["frac" "*"] "Frac(tional) multiplication."] - [Frac f./ ["frac" "/"] "Frac(tional) division."] - [Frac f.% ["frac" "%"] "Frac(tional) remainder."] + [Deg d.+ ["deg" "+"] "Deg(ree) addition."] + [Deg d.- ["deg" "-"] "Deg(ree) substraction."] + [Deg d.* ["deg" "*"] "Deg(ree) multiplication."] + [Deg d./ ["deg" "/"] "Deg(ree) division."] + [Deg d.% ["deg" "%"] "Deg(ree) remainder."] [Real r.+ ["jvm" "dadd"] "Real addition."] [Real r.- ["jvm" "dsub"] "Real substraction."] @@ -2171,7 +2171,7 @@ (do-template [ ] [(def:''' #export ( left right) - (list [["lux" "doc"] (#TextM )]) + (list [["lux" "doc"] (#TextA )]) (-> ) (if ( right left) left @@ -2183,8 +2183,8 @@ [i.min Int i.< "Int(eger) minimum."] [i.max Int i.> "Int(eger) maximum."] - [f.min Frac f.< "Frac(tional) minimum."] - [f.max Frac f.> "Frac(tional) maximum."] + [d.min Deg d.< "Deg(ree) minimum."] + [d.max Deg d.> "Deg(ree) maximum."] [r.min Real r.< "Real minimum."] [r.max Real r.> "Real minimum."] @@ -2196,7 +2196,7 @@ (i.= 0 (i.% div n))) (def:''' #export (not x) - (list [["lux" "doc"] (#TextM "## Boolean negation. + (list [["lux" "doc"] (#TextA "## Boolean negation. (not true) == false @@ -2215,9 +2215,9 @@ (get name bindings))] (let' [[def-type def-meta def-value] (_lux_: Def gdef)] (_lux_case (get-meta ["lux" "macro?"] def-meta) - (#Some (#BoolM true)) + (#Some (#BoolA true)) (_lux_case (get-meta ["lux" "export?"] def-meta) - (#Some (#BoolM true)) + (#Some (#BoolA true)) (#Some (_lux_:! Macro def-value)) _ @@ -2227,7 +2227,7 @@ _ (_lux_case (get-meta ["lux" "alias"] def-meta) - (#Some (#IdentM [r-module r-name])) + (#Some (#IdentA [r-module r-name])) (find-macro' modules current-module r-module r-name) _ @@ -2400,7 +2400,7 @@ type)) (macro:' #export (type tokens) - (list [["lux" "doc"] (#TextM "## Takes a type expression and returns it's representation as data-structure. + (list [["lux" "doc"] (#TextA "## Takes a type expression and returns it's representation as data-structure. (type (All [a] (Maybe (List a))))")]) (_lux_case tokens (#Cons type #Nil) @@ -2417,7 +2417,7 @@ (fail "Wrong syntax for type"))) (macro:' #export (: tokens) - (list [["lux" "doc"] (#TextM "## The type-annotation macro. + (list [["lux" "doc"] (#TextA "## The type-annotation macro. (: (List Int) (list 1 2 3))")]) (_lux_case tokens (#Cons type (#Cons value #Nil)) @@ -2427,7 +2427,7 @@ (fail "Wrong syntax for :"))) (macro:' #export (:! tokens) - (list [["lux" "doc"] (#TextM "## The type-coercion macro. + (list [["lux" "doc"] (#TextA "## The type-coercion macro. (:! Dinosaur (list 1 2 3))")]) (_lux_case tokens (#Cons type (#Cons value #Nil)) @@ -2523,7 +2523,7 @@ (symbol$ ["" ($_ Text/append "__gensym__" prefix (->Text seed))])))) (macro:' #export (Rec tokens) - (list [["lux" "doc"] (#TextM "## Parameter-less recursive types. + (list [["lux" "doc"] (#TextA "## Parameter-less recursive types. ## A name has to be given to the whole type, to use it within it's body. (Rec Self [Int (List Self)])")]) @@ -2536,7 +2536,7 @@ (fail "Wrong syntax for Rec"))) (macro:' #export (exec tokens) - (list [["lux" "doc"] (#TextM "## Sequential execution of expressions (great for side-effects). + (list [["lux" "doc"] (#TextA "## Sequential execution of expressions (great for side-effects). (exec (log! \"#1\") (log! \"#2\") @@ -2608,10 +2608,10 @@ (-> Nat Text) (_lux_proc ["nat" "encode"] [x])) -(def:''' (Frac->Text x) +(def:''' (Deg->Text x) #Nil - (-> Frac Text) - (_lux_proc ["frac" "encode"] [x])) + (-> Deg Text) + (_lux_proc ["deg" "encode"] [x])) (def:' (ast-to-text ast) (-> AST Text) @@ -2625,8 +2625,8 @@ [_ (#IntS value)] (->Text value) - [_ (#FracS value)] - (Frac->Text value) + [_ (#DegS value)] + (Deg->Text value) [_ (#RealS value)] (->Text value) @@ -2703,7 +2703,7 @@ (fold Text/append "")))))) (macro:' #export (case tokens) - (list [["lux" "doc"] (#TextM "## The pattern-matching macro. + (list [["lux" "doc"] (#TextA "## The pattern-matching macro. ## Allows the usage of macros within the patterns to provide custom syntax. (case (: (List Int) (list 1 2 3)) (#Cons x (#Cons y (#Cons z #Nil))) @@ -2721,7 +2721,7 @@ (fail "Wrong syntax for case"))) (macro:' #export (^ tokens) - (list [["lux" "doc"] (#TextM "## Macro-expanding patterns. + (list [["lux" "doc"] (#TextA "## Macro-expanding patterns. ## It's a special macro meant to be used with 'case'. (case (: (List Int) (list 1 2 3)) (^ (list x y z)) @@ -2744,7 +2744,7 @@ (fail "Wrong syntax for ^ macro"))) (macro:' #export (^or tokens) - (list [["lux" "doc"] (#TextM "## Or-patterns. + (list [["lux" "doc"] (#TextA "## Or-patterns. ## It's a special macro meant to be used with 'case'. (type: Weekday #Monday @@ -2787,7 +2787,7 @@ false)) (macro:' #export (let tokens) - (list [["lux" "doc"] (#TextM "## Creates local bindings. + (list [["lux" "doc"] (#TextA "## Creates local bindings. ## Can (optionally) use pattern-matching macros when binding. (let [x (foo bar) y (baz quux)] @@ -2811,7 +2811,7 @@ (fail "Wrong syntax for let"))) (macro:' #export (lambda tokens) - (list [["lux" "doc"] (#TextM "## Syntax for creating functions. + (list [["lux" "doc"] (#TextA "## Syntax for creating functions. ## Allows for giving the function itself a name, for the sake of recursion. (: (All [a b] (-> a b a)) (lambda [x y] x)) @@ -2850,28 +2850,28 @@ (-> AST (Lux AST)) (case ast [_ (#BoolS value)] - (return (form$ (list (tag$ ["lux" "BoolM"]) (bool$ value)))) + (return (form$ (list (tag$ ["lux" "BoolA"]) (bool$ value)))) [_ (#NatS value)] - (return (form$ (list (tag$ ["lux" "NatM"]) (nat$ value)))) + (return (form$ (list (tag$ ["lux" "NatA"]) (nat$ value)))) [_ (#IntS value)] - (return (form$ (list (tag$ ["lux" "IntM"]) (int$ value)))) + (return (form$ (list (tag$ ["lux" "IntA"]) (int$ value)))) - [_ (#FracS value)] - (return (form$ (list (tag$ ["lux" "FracM"]) (frac$ value)))) + [_ (#DegS value)] + (return (form$ (list (tag$ ["lux" "DegA"]) (deg$ value)))) [_ (#RealS value)] - (return (form$ (list (tag$ ["lux" "RealM"]) (real$ value)))) + (return (form$ (list (tag$ ["lux" "RealA"]) (real$ value)))) [_ (#CharS value)] - (return (form$ (list (tag$ ["lux" "CharM"]) (char$ value)))) + (return (form$ (list (tag$ ["lux" "CharA"]) (char$ value)))) [_ (#TextS value)] - (return (form$ (list (tag$ ["lux" "TextM"]) (text$ value)))) + (return (form$ (list (tag$ ["lux" "TextA"]) (text$ value)))) [_ (#TagS [prefix name])] - (return (form$ (list (tag$ ["lux" "IdentM"]) (tuple$ (list (text$ prefix) (text$ name)))))) + (return (form$ (list (tag$ ["lux" "IdentA"]) (tuple$ (list (text$ prefix) (text$ name)))))) (^or [_ (#FormS _)] [_ (#SymbolS _)]) (return ast) @@ -2879,7 +2879,7 @@ [_ (#TupleS xs)] (do Monad [=xs (mapM Monad process-def-meta-value xs)] - (wrap (form$ (list (tag$ ["lux" "ListM"]) (untemplate-list =xs))))) + (wrap (form$ (list (tag$ ["lux" "ListA"]) (untemplate-list =xs))))) [_ (#RecordS kvs)] (do Monad @@ -2893,9 +2893,9 @@ (wrap (tuple$ (list (text$ =k) =v)))) _ - (fail (Text/append "Wrong syntax for DictM key: " (ast-to-text k)))))) + (fail (Text/append "Wrong syntax for DictA key: " (ast-to-text k)))))) kvs)] - (wrap (form$ (list (tag$ ["lux" "DictM"]) (untemplate-list =xs))))) + (wrap (form$ (list (tag$ ["lux" "DictA"]) (untemplate-list =xs))))) )) (def:' (process-def-meta ast) @@ -2929,15 +2929,15 @@ _ (` (#;Cons [["lux" "func-args"] - (#;ListM (list (~@ (map (lambda [arg] - (` (#;TextM (~ (text$ (ast-to-text arg)))))) + (#;ListA (list (~@ (map (lambda [arg] + (` (#;TextA (~ (text$ (ast-to-text arg)))))) args))))] (~ meta))))) (def:' (with-type-args args) (-> (List AST) AST) - (` {#;type-args (#;ListM (list (~@ (map (lambda [arg] - (` (#;TextM (~ (text$ (ast-to-text arg)))))) + (` {#;type-args (#;ListA (list (~@ (map (lambda [arg] + (` (#;TextA (~ (text$ (ast-to-text arg)))))) args))))})) (def:' Export-Level @@ -2972,7 +2972,7 @@ (list (' #hidden)))) (def:''' #export (log! message) - (list [["lux" "doc"] (#TextM "Logs message to standard output. + (list [["lux" "doc"] (#TextA "Logs message to standard output. Useful for debugging.")]) (-> Text Unit) @@ -2980,7 +2980,7 @@ [(_lux_proc ["jvm" "getstatic:java.lang.System:out"] []) message])) (macro:' #export (def: tokens) - (list [["lux" "doc"] (#TextM "## Defines global constants/functions. + (list [["lux" "doc"] (#TextA "## Defines global constants/functions. (def: (rejoin-pair pair) (-> [AST AST] (List AST)) (let [[left right] pair] @@ -3070,7 +3070,7 @@ base)) (macro:' #export (macro: tokens) - (list [["lux" "doc"] (#TextM "Macro-definition macro. + (list [["lux" "doc"] (#TextA "Macro-definition macro. (macro: #export (ident-for tokens) (case tokens @@ -3616,7 +3616,7 @@ (#Some tags) (` {#;tags [(~@ (map (: (-> Text AST) (lambda' [tag] - (form$ (list (tag$ ["lux" "TextM"]) + (form$ (list (tag$ ["lux" "TextA"]) (text$ tag))))) tags))] #;type? true}) @@ -3956,7 +3956,7 @@ (lambda [[name [def-type def-meta def-value]]] (case [(get-meta ["lux" "export?"] def-meta) (get-meta ["lux" "hidden?"] def-meta)] - [(#Some (#BoolM true)) #;None] + [(#Some (#BoolA true)) #;None] (list name) _ @@ -4436,7 +4436,7 @@ (lambda [def] (` (;_lux_def (~ (symbol$ ["" def])) (~ (symbol$ [module-name def])) - (#Cons [["lux" "alias"] (#IdentM [(~ (text$ module-name)) (~ (text$ def))])] + (#Cons [["lux" "alias"] (#IdentA [(~ (text$ module-name)) (~ (text$ def))])] #Nil))))) defs') openings (join-map (: (-> Openings (List AST)) @@ -4782,7 +4782,7 @@ ([#BoolS] [#NatS] [#IntS] - [#FracS] + [#DegS] [#RealS] [#CharS] [#TextS] @@ -4903,7 +4903,7 @@ ([#BoolS ->Text] [#NatS Nat->Text] [#IntS ->Text] - [#FracS Frac->Text] + [#DegS Deg->Text] [#RealS ->Text] [#CharS Char/encode] [#TextS Text/encode] @@ -4957,7 +4957,7 @@ (if (< 10 count) (recur (i.inc count) (f x)) x)))"} - (return (list (` (#;TextM (~ (|> tokens + (return (list (` (#;TextA (~ (|> tokens (map (. doc-fragment->Text identify-doc-fragment)) Text/join Text/trim @@ -5102,7 +5102,7 @@ (def: (place-tokens label tokens target) (-> Text (List AST) AST (Maybe (List AST))) (case target - (^or [_ (#BoolS _)] [_ (#NatS _)] [_ (#IntS _)] [_ (#FracS _)] [_ (#RealS _)] [_ (#CharS _)] [_ (#TextS _)] [_ (#TagS _)]) + (^or [_ (#BoolS _)] [_ (#NatS _)] [_ (#IntS _)] [_ (#DegS _)] [_ (#RealS _)] [_ (#CharS _)] [_ (#TextS _)] [_ (#TagS _)]) (#Some (list target)) [_ (#SymbolS [prefix name])] @@ -5193,7 +5193,7 @@ (["Bool"] ["Nat"] ["Int"] - ["Frac"] + ["Deg"] ["Real"] ["Char"] ["Text"]) @@ -5216,7 +5216,7 @@ (["Bool" Bool bool$] ["Nat" Nat nat$] ["Int" Int int$] - ["Frac" Frac frac$] + ["Deg" Deg deg$] ["Real" Real real$] ["Char" Char char$] ["Text" Text text$]) @@ -5577,11 +5577,11 @@ (-> ) (_lux_proc [input]))] - [int-to-nat ["int" "to-nat"] Int Nat] - [nat-to-int ["nat" "to-int"] Nat Int] + [int-to-nat ["int" "to-nat"] Int Nat] + [nat-to-int ["nat" "to-int"] Nat Int] - [real-to-frac ["real" "to-frac"] Real Frac] - [frac-to-real ["frac" "to-real"] Frac Real] + [real-to-deg ["real" "to-deg"] Real Deg] + [deg-to-real ["deg" "to-real"] Deg Real] ) (macro: #export (type-of tokens) diff --git a/stdlib/source/lux/compiler.lux b/stdlib/source/lux/compiler.lux index 374556972..367217524 100644 --- a/stdlib/source/lux/compiler.lux +++ b/stdlib/source/lux/compiler.lux @@ -170,14 +170,14 @@ _ #;None))] - [get-bool-ann #;BoolM Bool] - [get-int-ann #;IntM Int] - [get-real-ann #;RealM Real] - [get-char-ann #;CharM Char] - [get-text-ann #;TextM Text] - [get-ident-ann #;IdentM Ident] - [get-list-ann #;ListM (List Ann-Value)] - [get-dict-ann #;DictM (List [Text Ann-Value])] + [get-bool-ann #;BoolA Bool] + [get-int-ann #;IntA Int] + [get-real-ann #;RealA Real] + [get-char-ann #;CharA Char] + [get-text-ann #;TextA Text] + [get-ident-ann #;IdentA Ident] + [get-list-ann #;ListA (List Ann-Value)] + [get-dict-ann #;DictA (List [Text Ann-Value])] ) (def: #export (get-doc anns) @@ -189,7 +189,7 @@ {#;doc "Finds out whether an annotation-as-a-flag is set (has value 'true')."} (-> Ident Anns Bool) (case (get-ann flag-name anns) - (#;Some (#;BoolM true)) + (#;Some (#;BoolA true)) true _ @@ -197,7 +197,7 @@ (do-template [ ] [(def: #export - {#;doc (#;TextM ($_ Text/append "Checks whether a definition is " "."))} + {#;doc (#;TextA ($_ Text/append "Checks whether a definition is " "."))} (-> Anns Bool) (flag-set? (ident-for )))] @@ -220,13 +220,13 @@ _ #;None))] - [try-mlist #;ListM (List Ann-Value)] - [try-mtext #;TextM Text] + [try-mlist #;ListA (List Ann-Value)] + [try-mtext #;TextA Text] ) (do-template [ ] [(def: #export ( anns) - {#;doc (#;TextM ($_ Text/append "Looks up the arguments of a " "."))} + {#;doc (#;TextA ($_ Text/append "Looks up the arguments of a " "."))} (-> Anns (List Text)) (default (list) (do Monad @@ -248,7 +248,7 @@ (or (export? def-anns) (Text/= module this-module))) (#;Some (:! Macro def-value)) (case (get-ann ["lux" "alias"] def-anns) - (#;Some (#;IdentM [r-module r-name])) + (#;Some (#;IdentA [r-module r-name])) (find-macro' modules this-module r-module r-name) _ @@ -602,7 +602,7 @@ [def-name (normalize def-name) [_ def-anns _] (find-def def-name)] (case (get-ann (ident-for #;alias) def-anns) - (#;Some (#;IdentM real-def-name)) + (#;Some (#;IdentA real-def-name)) (wrap real-def-name) _ diff --git a/stdlib/source/lux/control/ord.lux b/stdlib/source/lux/control/ord.lux index 0200d738a..8bd4ed906 100644 --- a/stdlib/source/lux/control/ord.lux +++ b/stdlib/source/lux/control/ord.lux @@ -18,7 +18,9 @@ (do-template [] [(: (-> a a Bool) )] - [<] [<=] [>] [>=])) + [<] [<=] [>] [>=] + ) + ) ## [Values] (def: #export (ord eq <) @@ -43,4 +45,5 @@ (if (:: ord y x) x y))] [max >] - [min <]) + [min <] + ) diff --git a/stdlib/source/lux/data/format/json.lux b/stdlib/source/lux/data/format/json.lux index d9ef60605..66ad6c093 100644 --- a/stdlib/source/lux/data/format/json.lux +++ b/stdlib/source/lux/data/format/json.lux @@ -190,7 +190,7 @@ (do-template [ ] [(def: #export ( key json) - {#;doc (#;TextM (format "A JSON object field getter for " "."))} + {#;doc (#;TextA (format "A JSON object field getter for " "."))} (-> Text JSON (Error )) (case (get key json) (#;Right ( value)) @@ -211,7 +211,7 @@ (do-template [ ] [(def: #export ( value) - {#;doc (#;TextM (format "A JSON generator for " "."))} + {#;doc (#;TextA (format "A JSON generator for " "."))} (Gen ) ( value))] @@ -398,7 +398,7 @@ ## Syntax (do-template [
]
   [(def: #export ( json)
-     {#;doc (#;TextM (format "Reads a JSON value as "  "."))}
+     {#;doc (#;TextA (format "Reads a JSON value as "  "."))}
      (Parser )
      (case json
        ( value)
@@ -416,7 +416,7 @@
 
 (do-template [       
]
   [(def: #export ( test json)
-     {#;doc (#;TextM (format "Asks whether a JSON value is a "  "."))}
+     {#;doc (#;TextA (format "Asks whether a JSON value is a "  "."))}
      (->  (Parser Bool))
      (case json
        ( value)
@@ -426,7 +426,7 @@
        (#;Left (format "JSON value is not a "  ": " (show-json json)))))
 
    (def: #export ( test json)
-     {#;doc (#;TextM (format "Ensures a JSON value is a "  "."))}
+     {#;doc (#;TextA (format "Ensures a JSON value is a "  "."))}
      (->  (Parser Unit))
      (case json
        ( value)
diff --git a/stdlib/source/lux/data/number.lux b/stdlib/source/lux/data/number.lux
index c5b3277f8..695f9c7b9 100644
--- a/stdlib/source/lux/data/number.lux
+++ b/stdlib/source/lux/data/number.lux
@@ -22,7 +22,7 @@
 
   [ Nat n.=]
   [ Int i.=]
-  [Frac f.=]
+  [Deg d.=]
   [Real r.=]
   )
 
@@ -36,7 +36,7 @@
 
   [ Nat  Eq n.< n.<= n.> n.>=]
   [ Int  Eq i.< i.<= i.> i.>=]
-  [Frac Eq f.< f.<= f.> f.>=]
+  [Deg Eq d.< d.<= d.> d.>=]
   [Real Eq r.< r.<= r.> r.>=]
   )
 
@@ -79,17 +79,17 @@
   [Real Ord r.+ r.- r.* r./ r.% r.= r.< 0.0 1.0 -1.0]
   )
 
-(struct: #export _ (Number Frac)
-  (def: ord Ord)
-  (def: + f.+)
-  (def: - f.-)
-  (def: * f.*)
-  (def: / f./)
-  (def: % f.%)
-  (def: (negate x) (f.- x (_lux_proc ["frac" "max-value"] [])))
+(struct: #export _ (Number Deg)
+  (def: ord Ord)
+  (def: + d.+)
+  (def: - d.-)
+  (def: * d.*)
+  (def: / d./)
+  (def: % d.%)
+  (def: (negate x) (d.- x (_lux_proc ["deg" "max-value"] [])))
   (def: abs id)
   (def: (signum x)
-    (_lux_proc ["frac" "max-value"] []))
+    (_lux_proc ["deg" "max-value"] []))
   )
 
 (do-template [   ]
@@ -110,7 +110,7 @@
   [ Nat (_lux_proc ["nat"  "max-value"] [])                            (_lux_proc ["nat"  "min-value"] [])]
   [ Int (_lux_proc ["jvm"  "getstatic:java.lang.Long:MAX_VALUE"] [])   (_lux_proc ["jvm"  "getstatic:java.lang.Long:MIN_VALUE"] [])]
   [Real (_lux_proc ["jvm"  "getstatic:java.lang.Double:MAX_VALUE"] []) (_lux_proc ["jvm"  "getstatic:java.lang.Double:MIN_VALUE"] [])]
-  [Frac (_lux_proc ["frac" "max-value"] [])                            (_lux_proc ["frac" "min-value"] [])])
+  [Deg (_lux_proc ["deg" "max-value"] [])                            (_lux_proc ["deg" "min-value"] [])])
 
 (do-template [   ]
   [(struct: #export  (Monoid )
@@ -129,10 +129,10 @@
   [Mul@Monoid Real 1.0                       r.*]
   [Max@Monoid Real (:: Bounded bottom) r.max]
   [Min@Monoid Real (:: Bounded top)    r.min]
-  [Add@Monoid Frac (:: Bounded bottom) f.+]
-  [Mul@Monoid Frac (:: Bounded top)    f.*]
-  [Max@Monoid Frac (:: Bounded bottom) f.max]
-  [Min@Monoid Frac (:: Bounded top)    f.min]
+  [Add@Monoid Deg (:: Bounded bottom) d.+]
+  [Mul@Monoid Deg (:: Bounded top)    d.*]
+  [Max@Monoid Deg (:: Bounded bottom) d.max]
+  [Min@Monoid Deg (:: Bounded top)    d.min]
   )
 
 (def: (text.replace pattern value template)
@@ -153,7 +153,7 @@
          (#;Left ))))]
 
   [Nat  ["nat"  "encode"] ["nat"  "decode"] "Couldn't decode Nat"]
-  [Frac ["frac" "encode"] ["frac" "decode"] "Couldn't decode Frac"]
+  [Deg ["deg" "encode"] ["deg" "decode"] "Couldn't decode Deg"]
   )
 
 (def: clean-number
diff --git a/stdlib/source/lux/data/struct/set.lux b/stdlib/source/lux/data/struct/set.lux
index 5f828ba43..711ae4553 100644
--- a/stdlib/source/lux/data/struct/set.lux
+++ b/stdlib/source/lux/data/struct/set.lux
@@ -47,9 +47,9 @@
   (All [a] (-> (Set a) (Set a) (Set a)))
   (dict;merge xs yx))
 
-(def: #export (difference subs base)
+(def: #export (difference sub base)
   (All [a] (-> (Set a) (Set a) (Set a)))
-  (List/fold remove base (to-list subs)))
+  (List/fold remove base (to-list sub)))
 
 (def: #export (intersection filter base)
   (All [a] (-> (Set a) (Set a) (Set a)))
diff --git a/stdlib/source/lux/data/struct/tree.lux b/stdlib/source/lux/data/struct/tree.lux
deleted file mode 100644
index 8620e46a7..000000000
--- a/stdlib/source/lux/data/struct/tree.lux
+++ /dev/null
@@ -1,60 +0,0 @@
-##  Copyright (c) Eduardo Julian. All rights reserved.
-##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
-##  If a copy of the MPL was not distributed with this file,
-##  You can obtain one at http://mozilla.org/MPL/2.0/.
-
-(;module:
-  lux
-  (lux (control monad
-                eq)
-       (data (struct [list "" Monad]))
-       [compiler]
-       (macro [ast]
-              ["s" syntax #+ syntax: Syntax])))
-
-## [Types]
-(type: #export (Tree a)
-  {#value a
-   #children (List (Tree a))})
-
-## [Values]
-(def: #export (flatten tree)
-  (All [a] (-> (Tree a) (List a)))
-  (#;Cons (get@ #value tree)
-          (join (map flatten (get@ #children tree)))))
-
-(def: #export (leaf value)
-  (All [a] (-> a (Tree a)))
-  {#value value
-   #children (list)})
-
-(def: #export (branch value children)
-  (All [a] (-> a (List (Tree a)) (Tree a)))
-  {#value value
-   #children children})
-
-## [Syntax]
-(type: #rec Tree-AST
-  [AST (List Tree-AST)])
-
-(def: (tree^ _)
-  (-> Unit (Syntax Tree-AST))
-  (s;either (s;record (s;seq s;any (s;tuple (s;some (lambda [state] ((tree^ []) state))))))
-            (s;seq s;any (:: s;Monad wrap (list)))))
-
-(syntax: #export (tree type [root (tree^ [])])
-  {#;doc (doc "Tree literals."
-              (tree Int 10)
-              (tree Int {10 [20
-                             {30 []}
-                             40]}))}
-  (wrap (list (` (: (Tree (~ type))
-                    (~ (loop [[value children] root]
-                         (` {#value (~ value)
-                             #children (list (~@ (map recur children)))}))))))))
-
-## [Structs]
-(struct: #export (Eq Eq) (All [a] (-> (Eq a) (Eq (Tree a))))
-  (def: (= tx ty)
-    (and (:: Eq = (get@ #value tx) (get@ #value ty))
-         (:: (list;Eq (Eq Eq)) = (get@ #children tx) (get@ #children ty)))))
diff --git a/stdlib/source/lux/data/struct/tree/rose.lux b/stdlib/source/lux/data/struct/tree/rose.lux
new file mode 100644
index 000000000..8620e46a7
--- /dev/null
+++ b/stdlib/source/lux/data/struct/tree/rose.lux
@@ -0,0 +1,60 @@
+##  Copyright (c) Eduardo Julian. All rights reserved.
+##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+##  If a copy of the MPL was not distributed with this file,
+##  You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(;module:
+  lux
+  (lux (control monad
+                eq)
+       (data (struct [list "" Monad]))
+       [compiler]
+       (macro [ast]
+              ["s" syntax #+ syntax: Syntax])))
+
+## [Types]
+(type: #export (Tree a)
+  {#value a
+   #children (List (Tree a))})
+
+## [Values]
+(def: #export (flatten tree)
+  (All [a] (-> (Tree a) (List a)))
+  (#;Cons (get@ #value tree)
+          (join (map flatten (get@ #children tree)))))
+
+(def: #export (leaf value)
+  (All [a] (-> a (Tree a)))
+  {#value value
+   #children (list)})
+
+(def: #export (branch value children)
+  (All [a] (-> a (List (Tree a)) (Tree a)))
+  {#value value
+   #children children})
+
+## [Syntax]
+(type: #rec Tree-AST
+  [AST (List Tree-AST)])
+
+(def: (tree^ _)
+  (-> Unit (Syntax Tree-AST))
+  (s;either (s;record (s;seq s;any (s;tuple (s;some (lambda [state] ((tree^ []) state))))))
+            (s;seq s;any (:: s;Monad wrap (list)))))
+
+(syntax: #export (tree type [root (tree^ [])])
+  {#;doc (doc "Tree literals."
+              (tree Int 10)
+              (tree Int {10 [20
+                             {30 []}
+                             40]}))}
+  (wrap (list (` (: (Tree (~ type))
+                    (~ (loop [[value children] root]
+                         (` {#value (~ value)
+                             #children (list (~@ (map recur children)))}))))))))
+
+## [Structs]
+(struct: #export (Eq Eq) (All [a] (-> (Eq a) (Eq (Tree a))))
+  (def: (= tx ty)
+    (and (:: Eq = (get@ #value tx) (get@ #value ty))
+         (:: (list;Eq (Eq Eq)) = (get@ #children tx) (get@ #children ty)))))
diff --git a/stdlib/source/lux/data/struct/tree/zipper.lux b/stdlib/source/lux/data/struct/tree/zipper.lux
new file mode 100644
index 000000000..74dbd024f
--- /dev/null
+++ b/stdlib/source/lux/data/struct/tree/zipper.lux
@@ -0,0 +1,197 @@
+##  Copyright (c) Eduardo Julian. All rights reserved.
+##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+##  If a copy of the MPL was not distributed with this file,
+##  You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(;module:
+  lux
+  (lux (data (struct [list "" Monad Fold "List/" Monoid]
+                     (tree [rose #+ Tree])
+                     [stack #+ Stack]))
+       [compiler]
+       (macro [ast]
+              ["s" syntax #+ syntax: Syntax])))
+
+## Adapted from the clojure.zip namespace in the Clojure standard library.
+
+## [Types]
+(type: #export (Zipper a)
+  {#;doc "Tree zippers, for easy navigation and editing over trees."}
+  {#parent (Maybe (Zipper a))
+   #lefts (Stack (Tree a))
+   #rights (Stack (Tree a))
+   #node (Tree a)})
+
+## [Values]
+(def: #export (from-tree tree)
+  (All [a] (-> (Tree a) (Zipper a)))
+  {#parent #;None
+   #lefts stack;empty
+   #rights stack;empty
+   #node tree})
+
+(def: #export (to-tree zipper)
+  (All [a] (-> (Zipper a) (Tree a)))
+  (get@ #node zipper))
+
+(def: #export (value zipper)
+  (All [a] (-> (Zipper a) a))
+  (|> zipper (get@ #node) (get@ #rose;value)))
+
+(def: #export (children zipper)
+  (All [a] (-> (Zipper a) (List (Tree a))))
+  (|> zipper (get@ #node) (get@ #rose;children)))
+
+(def: #export (branch? zipper)
+  (All [a] (-> (Zipper a) Bool))
+  (|> zipper children list;empty? not))
+
+(def: #export (leaf? zipper)
+  (All [a] (-> (Zipper a) Bool))
+  (|> zipper branch? not))
+
+(def: #export (parent zipper)
+  (All [a] (-> (Zipper a) (Maybe (Zipper a))))
+  (get@ #parent zipper))
+
+(def: #export (down zipper)
+  (All [a] (-> (Zipper a) (Zipper a)))
+  (case (children zipper)
+    #;Nil
+    zipper
+
+    (#;Cons chead ctail)
+    {#parent (#;Some zipper)
+     #lefts stack;empty
+     #rights ctail
+     #node chead}))
+
+(def: #export (up zipper)
+  (All [a] (-> (Zipper a) (Zipper a)))
+  (case (get@ #parent zipper)
+    #;None
+    zipper
+
+    (#;Some parent)
+    (|> parent
+        (update@ #node (: (-> (Tree ($ +0)) (Tree ($ +0)))
+                          (lambda [node]
+                            (set@ #rose;children (List/append (list;reverse (get@ #lefts zipper))
+                                                              (#;Cons (get@ #node zipper)
+                                                                      (get@ #rights zipper)))
+                                  node)))))))
+
+(def: #export (root zipper)
+  (All [a] (-> (Zipper a) (Zipper a)))
+  (loop [zipper zipper]
+    (case (get@ #parent zipper)
+      #;None     zipper
+      (#;Some _) (recur (up zipper)))))
+
+(do-template [   ]
+  [(def: #export ( zipper)
+     (All [a] (-> (Zipper a) (Zipper a)))
+     (case (get@  zipper)
+       #;Nil
+       zipper
+
+       (#;Cons next side')
+       (|> zipper
+           (update@  (lambda [op-side]
+                                (#;Cons (get@ #node zipper) op-side)))
+           (set@  side')
+           (set@ #node next))))
+
+   (def: #export ( zipper)
+     (All [a] (-> (Zipper a) (Zipper a)))
+     (fold (lambda [_] ) zipper (get@  zipper)))]
+
+  [right rightmost #rights #lefts]
+  [left  leftmost  #lefts  #rights]
+  )
+
+(def: #export (set value zipper)
+  (All [a] (-> a (Zipper a) (Zipper a)))
+  (set@ [#node #rose;value] value zipper))
+
+(def: #export (update f zipper)
+  (All [a] (-> (-> a a) (Zipper a) (Zipper a)))
+  (update@ [#node #rose;value] f zipper))
+
+(def: #export (prepend-child value zipper)
+  (All [a] (-> a (Zipper a) (Zipper a)))
+  (update@ [#node #rose;children]
+           (lambda [children]
+             (#;Cons (rose;tree ($ +0) {value []})
+                     children))
+           zipper))
+
+(def: #export (append-child value zipper)
+  (All [a] (-> a (Zipper a) (Zipper a)))
+  (update@ [#node #rose;children]
+           (lambda [children]
+             (List/append children
+                          (list (rose;tree ($ +0) {value []}))))
+           zipper))
+
+(def: #export (remove zipper)
+  (All [a] (-> (Zipper a) (Maybe (Zipper a))))
+  (case (get@ #lefts zipper)
+    #;Nil
+    (case (get@ #parent zipper)
+      #;None
+      #;None
+
+      (#;Some next)
+      (#;Some (|> next
+                  (update@ [#node #rose;children] (|>. list;tail (default (list)))))))
+
+    (#;Cons next side)
+    (#;Some (|> zipper
+                (set@ #lefts side)
+                (set@ #node next)))))
+
+(do-template [ ]
+  [(def: #export ( value zipper)
+     (All [a] (-> a (Zipper a) (Maybe (Zipper a))))
+     (case (get@ #parent zipper)
+       #;None
+       #;None
+
+       _
+       (#;Some (|> zipper
+                   (update@  (lambda [side]
+                                     (#;Cons (rose;tree ($ +0) {value []})
+                                             side)))))))]
+
+  [insert-left  #lefts]
+  [insert-right #rights]
+  )
+
+(do-template [   ]
+  [(def: #export ( zipper)
+     (All [a] (-> (Zipper a) (Zipper a)))
+     (case (get@  zipper)
+       #;Nil
+       ( zipper)
+
+       _
+       ( zipper)))]
+
+  [next #rights right down]
+  [prev #lefts  left up]
+  )
+
+(def: #export (end? zipper)
+  (All [a] (-> (Zipper a) Bool))
+  (and (list;empty? (get@ #rights zipper))
+       (list;empty? (children zipper))))
+
+(def: #export (root? zipper)
+  (All [a] (-> (Zipper a) Bool))
+  (case (get@ #parent zipper)
+    #;None
+    true
+
+    _
+    false))
diff --git a/stdlib/source/lux/data/struct/zipper.lux b/stdlib/source/lux/data/struct/zipper.lux
deleted file mode 100644
index 2a447a65b..000000000
--- a/stdlib/source/lux/data/struct/zipper.lux
+++ /dev/null
@@ -1,197 +0,0 @@
-##  Copyright (c) Eduardo Julian. All rights reserved.
-##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
-##  If a copy of the MPL was not distributed with this file,
-##  You can obtain one at http://mozilla.org/MPL/2.0/.
-
-(;module:
-  lux
-  (lux (data (struct [list "" Monad Fold "List/" Monoid]
-                     [tree #+ Tree]
-                     [stack #+ Stack]))
-       [compiler]
-       (macro [ast]
-              ["s" syntax #+ syntax: Syntax])))
-
-## Adapted from the clojure.zip namespace in the Clojure standard library.
-
-## [Types]
-(type: #export (Zipper a)
-  {#;doc "Tree zippers, for easy navigation and editing over trees."}
-  {#parent (Maybe (Zipper a))
-   #lefts (Stack (Tree a))
-   #rights (Stack (Tree a))
-   #node (Tree a)})
-
-## [Values]
-(def: #export (from-tree tree)
-  (All [a] (-> (Tree a) (Zipper a)))
-  {#parent #;None
-   #lefts stack;empty
-   #rights stack;empty
-   #node tree})
-
-(def: #export (to-tree zipper)
-  (All [a] (-> (Zipper a) (Tree a)))
-  (get@ #node zipper))
-
-(def: #export (value zipper)
-  (All [a] (-> (Zipper a) a))
-  (|> zipper (get@ #node) (get@ #tree;value)))
-
-(def: #export (children zipper)
-  (All [a] (-> (Zipper a) (List (Tree a))))
-  (|> zipper (get@ #node) (get@ #tree;children)))
-
-(def: #export (branch? zipper)
-  (All [a] (-> (Zipper a) Bool))
-  (|> zipper children list;empty? not))
-
-(def: #export (leaf? zipper)
-  (All [a] (-> (Zipper a) Bool))
-  (|> zipper branch? not))
-
-(def: #export (parent zipper)
-  (All [a] (-> (Zipper a) (Maybe (Zipper a))))
-  (get@ #parent zipper))
-
-(def: #export (down zipper)
-  (All [a] (-> (Zipper a) (Zipper a)))
-  (case (children zipper)
-    #;Nil
-    zipper
-
-    (#;Cons chead ctail)
-    {#parent (#;Some zipper)
-     #lefts stack;empty
-     #rights ctail
-     #node chead}))
-
-(def: #export (up zipper)
-  (All [a] (-> (Zipper a) (Zipper a)))
-  (case (get@ #parent zipper)
-    #;None
-    zipper
-
-    (#;Some parent)
-    (|> parent
-        (update@ #node (: (-> (Tree ($ +0)) (Tree ($ +0)))
-                          (lambda [node]
-                            (set@ #tree;children (List/append (list;reverse (get@ #lefts zipper))
-                                                              (#;Cons (get@ #node zipper)
-                                                                      (get@ #rights zipper)))
-                                  node)))))))
-
-(def: #export (root zipper)
-  (All [a] (-> (Zipper a) (Zipper a)))
-  (loop [zipper zipper]
-    (case (get@ #parent zipper)
-      #;None     zipper
-      (#;Some _) (recur (up zipper)))))
-
-(do-template [   ]
-  [(def: #export ( zipper)
-     (All [a] (-> (Zipper a) (Zipper a)))
-     (case (get@  zipper)
-       #;Nil
-       zipper
-
-       (#;Cons next side')
-       (|> zipper
-           (update@  (lambda [op-side]
-                                (#;Cons (get@ #node zipper) op-side)))
-           (set@  side')
-           (set@ #node next))))
-
-   (def: #export ( zipper)
-     (All [a] (-> (Zipper a) (Zipper a)))
-     (fold (lambda [_] ) zipper (get@  zipper)))]
-
-  [right rightmost #rights #lefts]
-  [left  leftmost  #lefts  #rights]
-  )
-
-(def: #export (set value zipper)
-  (All [a] (-> a (Zipper a) (Zipper a)))
-  (set@ [#node #tree;value] value zipper))
-
-(def: #export (update f zipper)
-  (All [a] (-> (-> a a) (Zipper a) (Zipper a)))
-  (update@ [#node #tree;value] f zipper))
-
-(def: #export (prepend-child value zipper)
-  (All [a] (-> a (Zipper a) (Zipper a)))
-  (update@ [#node #tree;children]
-           (lambda [children]
-             (#;Cons (tree;tree ($ +0) {value []})
-                     children))
-           zipper))
-
-(def: #export (append-child value zipper)
-  (All [a] (-> a (Zipper a) (Zipper a)))
-  (update@ [#node #tree;children]
-           (lambda [children]
-             (List/append children
-                          (list (tree;tree ($ +0) {value []}))))
-           zipper))
-
-(def: #export (remove zipper)
-  (All [a] (-> (Zipper a) (Maybe (Zipper a))))
-  (case (get@ #lefts zipper)
-    #;Nil
-    (case (get@ #parent zipper)
-      #;None
-      #;None
-
-      (#;Some next)
-      (#;Some (|> next
-                  (update@ [#node #tree;children] (|>. list;tail (default (list)))))))
-
-    (#;Cons next side)
-    (#;Some (|> zipper
-                (set@ #lefts side)
-                (set@ #node next)))))
-
-(do-template [ ]
-  [(def: #export ( value zipper)
-     (All [a] (-> a (Zipper a) (Maybe (Zipper a))))
-     (case (get@ #parent zipper)
-       #;None
-       #;None
-
-       _
-       (#;Some (|> zipper
-                   (update@  (lambda [side]
-                                     (#;Cons (tree;tree ($ +0) {value []})
-                                             side)))))))]
-
-  [insert-left  #lefts]
-  [insert-right #rights]
-  )
-
-(do-template [   ]
-  [(def: #export ( zipper)
-     (All [a] (-> (Zipper a) (Zipper a)))
-     (case (get@  zipper)
-       #;Nil
-       ( zipper)
-
-       _
-       ( zipper)))]
-
-  [next #rights right down]
-  [prev #lefts  left up]
-  )
-
-(def: #export (end? zipper)
-  (All [a] (-> (Zipper a) Bool))
-  (and (list;empty? (get@ #rights zipper))
-       (list;empty? (children zipper))))
-
-(def: #export (root? zipper)
-  (All [a] (-> (Zipper a) Bool))
-  (case (get@ #parent zipper)
-    #;None
-    true
-
-    _
-    false))
diff --git a/stdlib/source/lux/data/text/format.lux b/stdlib/source/lux/data/text/format.lux
index ebcb3fc48..2ae5c62ca 100644
--- a/stdlib/source/lux/data/text/format.lux
+++ b/stdlib/source/lux/data/text/format.lux
@@ -40,7 +40,7 @@
   [%b     Bool  (:: bool;Codec encode)]
   [%n     Nat   (:: number;Codec encode)]
   [%i     Int   (:: number;Codec encode)]
-  [%f     Frac  (:: number;Codec encode)]
+  [%f     Deg  (:: number;Codec encode)]
   [%r     Real  (:: number;Codec encode)]
   [%c     Char  (:: char;Codec encode)]
   [%t     Text  (:: text;Codec encode)]
diff --git a/stdlib/source/lux/lexer.lux b/stdlib/source/lux/lexer.lux
index 787cbb0c5..ca8f7f5cf 100644
--- a/stdlib/source/lux/lexer.lux
+++ b/stdlib/source/lux/lexer.lux
@@ -317,7 +317,7 @@
 
 (do-template [   ]
   [(def: #export 
-     {#;doc (#;TextM ($_ Text/append "Only lex "  " characters."))}
+     {#;doc (#;TextA ($_ Text/append "Only lex "  " characters."))}
      (Lexer Char)
      (char-range  ))]
 
diff --git a/stdlib/source/lux/lexer/regex.lux b/stdlib/source/lux/lexer/regex.lux
new file mode 100644
index 000000000..5684a4465
--- /dev/null
+++ b/stdlib/source/lux/lexer/regex.lux
@@ -0,0 +1,491 @@
+##  Copyright (c) Eduardo Julian. All rights reserved.
+##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+##  If a copy of the MPL was not distributed with this file,
+##  You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(;module:
+  lux
+  (lux (control monad)
+       (data [char]
+             [text]
+             text/format
+             [number "Int/" Codec]
+             [product]
+             (struct [list "" Fold "List/" Monad]))
+       [compiler #- run]
+       (macro [ast]
+              [syntax #+ syntax:])
+       ["&" lexer #+ Lexer Monad]))
+
+## [Utils]
+(def: #hidden (->Text lexer^)
+  (-> (Lexer Char) (Lexer Text))
+  (do Monad
+    [output lexer^]
+    (wrap (char;as-text output))))
+
+(def: regex-char^
+  (Lexer Char)
+  (&;none-of "\\.|&()[]{}"))
+
+(def: escaped-char^
+  (Lexer Char)
+  (do Monad
+    [? (&;opt (&;char #"\\"))
+     char (case ?
+            (#;Some _) &;any
+            #;None     regex-char^)]
+    (wrap char)))
+
+(def: (local^ state lexer)
+  (All [a] (-> Text (Lexer a) (Lexer a)))
+  (lambda [old-state]
+    (case (lexer state)
+      (#;Left error)
+      (#;Left error)
+
+      (#;Right [_ value])
+      (#;Right [old-state value]))))
+
+(def: #hidden (refine^ refinement^ base^)
+  (All [a] (-> (Lexer a) (Lexer Text) (Lexer Text)))
+  (do Monad
+    [output base^
+     _ (local^ output refinement^)]
+    (wrap output)))
+
+(def: #hidden word^
+  (Lexer Char)
+  (&;either &;alpha-num
+            (&;char #"_")))
+
+(def: #hidden (join-text^ part^)
+  (-> (Lexer (List Text)) (Lexer Text))
+  (do Monad
+    [parts part^]
+    (wrap (text;join-with "" parts))))
+
+(def: identifier-char^
+  (Lexer Char)
+  (&;none-of "[]{}()s\"#;<>"))
+
+(def: identifier-part^
+  (Lexer Text)
+  (do Monad
+    [head (refine^ (&;not &;digit)
+                   (->Text identifier-char^))
+     tail (&;some' identifier-char^)]
+    (wrap (format head tail))))
+
+(def: (identifier^ current-module)
+  (-> Text (Lexer Ident))
+  (do Monad
+    []
+    ($_ &;either
+        (&;seq (wrap current-module) (&;_& (&;text ";;") identifier-part^))
+        (&;seq identifier-part^ (&;_& (&;text ";") identifier-part^))
+        (&;seq (wrap "lux") (&;_& (&;text ";") identifier-part^))
+        (&;seq (wrap "") identifier-part^))))
+
+(def: (re-var^ current-module)
+  (-> Text (Lexer AST))
+  (do Monad
+    [ident (&;enclosed ["\\@<" ">"] (identifier^ current-module))]
+    (wrap (` (: (Lexer Text) (~ (ast;symbol ident)))))))
+
+(def: re-char-range^
+  (Lexer AST)
+  (do Monad
+    [from regex-char^
+     _ (&;char #"-")
+     to regex-char^]
+    (wrap (` (&;char-range (~ (ast;char from)) (~ (ast;char to)))))))
+
+(def: re-char^
+  (Lexer AST)
+  (do Monad
+    [char escaped-char^]
+    (wrap (` (&;char (~ (ast;char char)))))))
+
+(def: re-char+^
+  (Lexer AST)
+  (do Monad
+    [base re-char^]
+    (wrap (` (->Text (~ base))))))
+
+(def: re-char-options^
+  (Lexer AST)
+  (do Monad
+    [options (&;many' escaped-char^)]
+    (wrap (` (&;one-of (~ (ast;text options)))))))
+
+(def: re-user-class^'
+  (Lexer AST)
+  (do Monad
+    [negate? (&;opt (&;char #"^"))
+     parts (&;many ($_ &;either
+                       re-char-range^
+                       re-char-options^))]
+    (wrap (case negate?
+            (#;Some _) (` (->Text (&;not ($_ &;either (~@ parts)))))
+            #;None     (` (->Text ($_ &;either (~@ parts))))))))
+
+(def: re-user-class^
+  (Lexer AST)
+  (do Monad
+    [_ (wrap [])
+     init re-user-class^'
+     rest (&;some (&;_& (&;text "&&") (&;enclosed ["[" "]"] re-user-class^')))]
+    (wrap (fold (lambda [refinement base]
+                  (` (refine^ (~ refinement) (~ base))))
+                init
+                rest))))
+
+(def: #hidden blank^
+  (Lexer Char)
+  (&;one-of " \t"))
+
+(def: #hidden ascii^
+  (Lexer Char)
+  (&;char-range #"\u0000" #"\u007F"))
+
+(def: #hidden control^
+  (Lexer Char)
+  (&;either (&;char-range #"\u0000" #"\u001F")
+            (&;char #"\u007F")))
+
+(def: #hidden punct^
+  (Lexer Char)
+  (&;one-of "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"))
+
+(def: #hidden graph^
+  (Lexer Char)
+  (&;either punct^ &;alpha-num))
+
+(def: #hidden print^
+  (Lexer Char)
+  (&;either graph^
+            (&;char #"\u0020")))
+
+(def: re-system-class^
+  (Lexer AST)
+  (do Monad
+    []
+    ($_ &;either
+        (&;_& (&;char #".") (wrap (` (->Text &;any))))
+        (&;_& (&;text "\\d") (wrap (` (->Text &;digit))))
+        (&;_& (&;text "\\D") (wrap (` (->Text (&;not &;digit)))))
+        (&;_& (&;text "\\s") (wrap (` (->Text  &;space))))
+        (&;_& (&;text "\\S") (wrap (` (->Text (&;not &;space)))))
+        (&;_& (&;text "\\w") (wrap (` (->Text word^))))
+        (&;_& (&;text "\\W") (wrap (` (->Text (&;not word^)))))
+        (&;_& (&;text "\\d") (wrap (` (->Text &;digit))))
+
+        (&;_& (&;text "\\p{Lower}") (wrap (` (->Text &;lower))))
+        (&;_& (&;text "\\p{Upper}") (wrap (` (->Text &;upper))))
+        (&;_& (&;text "\\p{Alpha}") (wrap (` (->Text &;alpha))))
+        (&;_& (&;text "\\p{Digit}") (wrap (` (->Text &;digit))))
+        (&;_& (&;text "\\p{Alnum}") (wrap (` (->Text &;alpha-num))))
+        (&;_& (&;text "\\p{Space}") (wrap (` (->Text &;space))))
+        (&;_& (&;text "\\p{HexDigit}") (wrap (` (->Text &;hex-digit))))
+        (&;_& (&;text "\\p{OctDigit}") (wrap (` (->Text &;oct-digit))))
+        (&;_& (&;text "\\p{Blank}") (wrap (` (->Text blank^))))
+        (&;_& (&;text "\\p{ASCII}") (wrap (` (->Text ascii^))))
+        (&;_& (&;text "\\p{Contrl}") (wrap (` (->Text control^))))
+        (&;_& (&;text "\\p{Punct}") (wrap (` (->Text punct^))))
+        (&;_& (&;text "\\p{Graph}") (wrap (` (->Text graph^))))
+        (&;_& (&;text "\\p{Print}") (wrap (` (->Text print^))))
+        )))
+
+(def: re-class^
+  (Lexer AST)
+  (&;either re-system-class^
+            (&;enclosed ["[" "]"] re-user-class^)))
+
+(def: int^
+  (Lexer Int)
+  (&;codec number;Codec (&;many' &;digit)))
+
+(def: re-back-reference^
+  (Lexer AST)
+  (&;either (do Monad
+              [_ (&;char #"\\")
+               id int^]
+              (wrap (` (&;text (~ (ast;symbol ["" (Int/encode id)]))))))
+            (do Monad
+              [_ (&;text "\\k<")
+               captured-name identifier-part^
+               _ (&;text ">")]
+              (wrap (` (&;text (~ (ast;symbol ["" captured-name]))))))))
+
+(def: (re-simple^ current-module)
+  (-> Text (Lexer AST))
+  ($_ &;either
+      re-class^
+      (re-var^ current-module)
+      re-back-reference^
+      re-char+^
+      ))
+
+(def: (re-simple-quantified^ current-module)
+  (-> Text (Lexer AST))
+  (do Monad
+    [base (re-simple^ current-module)
+     quantifier (&;one-of "?*+")]
+    (case quantifier
+      #"?"
+      (wrap (` (&;default "" (~ base))))
+      
+      #"*"
+      (wrap (` (join-text^ (&;some (~ base)))))
+      
+      _
+      (wrap (` (join-text^ (&;many (~ base)))))
+      )))
+
+(def: (re-counted-quantified^ current-module)
+  (-> Text (Lexer AST))
+  (do Monad
+    [base (re-simple^ current-module)]
+    (&;enclosed ["{" "}"]
+                ($_ &;either
+                    (do @
+                      [[from to] (&;seq int^ (&;_& (&;char #",") int^))]
+                      (wrap (` (join-text^ (&;between (~ (ast;nat (int-to-nat from)))
+                                                      (~ (ast;nat (int-to-nat to)))
+                                                      (~ base))))))
+                    (do @
+                      [limit (&;_& (&;char #",") int^)]
+                      (wrap (` (join-text^ (&;at-most (~ (ast;nat (int-to-nat limit))) (~ base))))))
+                    (do @
+                      [limit (&;&_ int^ (&;char #","))]
+                      (wrap (` (join-text^ (&;at-least (~ (ast;nat (int-to-nat limit))) (~ base))))))
+                    (do @
+                      [limit int^]
+                      (wrap (` (join-text^ (&;exactly (~ (ast;nat (int-to-nat limit))) (~ base))))))))))
+
+(def: (re-quantified^ current-module)
+  (-> Text (Lexer AST))
+  (&;either (re-simple-quantified^ current-module)
+            (re-counted-quantified^ current-module)))
+
+(def: (re-complex^ current-module)
+  (-> Text (Lexer AST))
+  ($_ &;either
+      (re-quantified^ current-module)
+      (re-simple^ current-module)))
+
+(def: #hidden _Text/append_
+  (-> Text Text Text)
+  (:: text;Monoid append))
+
+(type: Re-Group
+  #Non-Capturing
+  (#Capturing [(Maybe Text) Nat]))
+
+(def: (re-sequential^ capturing? re-scoped^ current-module)
+  (-> Bool
+      (-> Text (Lexer [Re-Group AST]))
+      Text
+      (Lexer [Nat AST]))
+  (do Monad
+    [parts (&;many (&;alt (re-complex^ current-module)
+                          (re-scoped^ current-module)))
+     #let [g!total (ast;symbol ["" "0total"])
+           g!temp (ast;symbol ["" "0temp"])
+           [_ names steps] (fold (: (-> (Either AST [Re-Group AST])
+                                        [Int (List AST) (List (List AST))]
+                                        [Int (List AST) (List (List AST))])
+                                    (lambda [part [idx names steps]]
+                                      (case part
+                                        (^or (#;Left complex) (#;Right [#Non-Capturing complex]))
+                                        [idx
+                                         names
+                                         (list& (list g!temp complex
+                                                      (' #let) (` [(~ g!total) (_Text/append_ (~ g!total) (~ g!temp))]))
+                                                steps)]
+                                        
+                                        (#;Right [(#Capturing [?name num-captures]) scoped])
+                                        (let [[idx! name!] (case ?name
+                                                             (#;Some _name)
+                                                             [idx (ast;symbol ["" _name])]
+
+                                                             #;None
+                                                             [(i.inc idx) (ast;symbol ["" (Int/encode idx)])])
+                                              access (if (n.> +0 num-captures)
+                                                       (` (product;left (~ name!)))
+                                                       name!)]
+                                          [idx!
+                                           (list& name! names)
+                                           (list& (list name! scoped
+                                                        (' #let) (` [(~ g!total) (_Text/append_ (~ g!total) (~ access))]))
+                                                  steps)])
+                                        )))
+                                 [0
+                                  (: (List AST) (list))
+                                  (: (List (List AST)) (list))]
+                                 parts)]]
+    (wrap [(if capturing?
+             (list;size names)
+             +0)
+           (` (do Monad
+                [(~ (' #let)) [(~ g!total) ""]
+                 (~@ (|> steps list;reverse List/join))]
+                ((~ (' wrap)) [(~ g!total) (~@ (list;reverse names))])))])
+    ))
+
+(def: #hidden (unflatten^ lexer)
+  (-> (Lexer Text) (Lexer [Text Unit]))
+  (&;seq lexer (:: Monad wrap [])))
+
+(def: #hidden (|||^ left right)
+  (All [l r] (-> (Lexer [Text l]) (Lexer [Text r]) (Lexer [Text (| l r)])))
+  (lambda [input]
+    (case (left input)
+      (#;Right [input' [lt lv]])
+      (#;Right [input' [lt (+0 lv)]])
+
+      (#;Left _)
+      (case (right input)
+        (#;Right [input' [rt rv]])
+        (#;Right [input' [rt (+1 rv)]])
+
+        (#;Left error)
+        (#;Left error)))))
+
+(def: #hidden (|||_^ left right)
+  (All [l r] (-> (Lexer [Text l]) (Lexer [Text r]) (Lexer Text)))
+  (lambda [input]
+    (case (left input)
+      (#;Right [input' [lt lv]])
+      (#;Right [input' lt])
+
+      (#;Left _)
+      (case (right input)
+        (#;Right [input' [rt rv]])
+        (#;Right [input' rt])
+
+        (#;Left error)
+        (#;Left error)))))
+
+(def: (prep-alternative [num-captures alt])
+  (-> [Nat AST] AST)
+  (if (n.> +0 num-captures)
+    alt
+    (` (unflatten^ (~ alt)))))
+
+(def: (re-alternative^ capturing? re-scoped^ current-module)
+  (-> Bool
+      (-> Text (Lexer [Re-Group AST]))
+      Text
+      (Lexer [Nat AST]))
+  (do Monad
+    [#let [sub^ (re-sequential^ capturing? re-scoped^ current-module)]
+     head sub^
+     tail (&;some (&;_& (&;char #"|") sub^))
+     #let [g!op (if capturing?
+                  (` |||^)
+                  (` |||_^))]]
+    (if (list;empty? tail)
+      (wrap head)
+      (wrap [(fold n.max (product;left head) (List/map product;left tail))
+             (` ($_ (~ g!op) (~ (prep-alternative head)) (~@ (List/map prep-alternative tail))))]))))
+
+(def: (re-scoped^ current-module)
+  (-> Text (Lexer [Re-Group AST]))
+  ($_ &;either
+      (do Monad
+        [_ (&;text "(?:")
+         [_ scoped] (re-alternative^ false re-scoped^ current-module)
+         _ (&;char #")")]
+        (wrap [#Non-Capturing scoped]))
+      (do Monad
+        [complex (re-complex^ current-module)]
+        (wrap [#Non-Capturing complex]))
+      (do Monad
+        [_ (&;text "(?<")
+         captured-name identifier-part^
+         _ (&;text ">")
+         [num-captures pattern] (re-alternative^ true re-scoped^ current-module)
+         _ (&;char #")")]
+        (wrap [(#Capturing [(#;Some captured-name) num-captures]) pattern]))
+      (do Monad
+        [_ (&;char #"(")
+         [num-captures pattern] (re-alternative^ true re-scoped^ current-module)
+         _ (&;char #")")]
+        (wrap [(#Capturing [#;None num-captures]) pattern]))))
+
+(def: (regex^ current-module)
+  (-> Text (Lexer AST))
+  (:: Monad map product;right (re-alternative^ true re-scoped^ current-module)))
+
+## [Syntax]
+(syntax: #export (regex [pattern syntax;text])
+  {#;doc (doc "Create lexers using regular-expression syntax."
+              "For example:"
+              
+              "Literals"
+              (regex "a")
+              
+              "Wildcards"
+              (regex ".")
+              
+              "Escaping"
+              (regex "\\.")
+              
+              "Character classes"
+              (regex "\\d")
+              (regex "\\p{Lower}")
+              (regex "[abc]")
+              (regex "[a-z]")
+              (regex "[a-zA-Z]")
+              (regex "[a-z&&[def]]")
+              
+              "Negation"
+              (regex "[^abc]")
+              (regex "[^a-z]")
+              (regex "[^a-zA-Z]")
+              (regex "[a-z&&[^bc]]")
+              (regex "[a-z&&[^m-p]]")
+              
+              "Combinations"
+              (regex "aa")
+              (regex "a?")
+              (regex "a*")
+              (regex "a+")
+              
+              "Specific amounts"
+              (regex "a{2}")
+              
+              "At least"
+              (regex "a{1,}")
+              
+              "At most"
+              (regex "a{,1}")
+              
+              "Between"
+              (regex "a{1,2}")
+              
+              "Groups"
+              (regex "a(.)c")
+              (regex "a(b+)c")
+              (regex "(\\d{3})-(\\d{3})-(\\d{4})")
+              (regex "(\\d{3})-(?:\\d{3})-(\\d{4})")
+              (regex "(?\\d{3})-\\k-(\\d{4})")
+              (regex "(?\\d{3})-\\k-(\\d{4})-\\0")
+              (regex "(\\d{3})-((\\d{3})-(\\d{4}))")
+              
+              "Alternation"
+              (regex "a|b")
+              (regex "a(.)(.)|b(.)(.)")
+              )}
+  (do @
+    [current-module compiler;current-module-name]
+    (case (&;run pattern
+                 (&;&_ (regex^ current-module) &;end))
+      (#;Left error)
+      (compiler;fail error)
+
+      (#;Right regex)
+      (wrap (list regex))
+      )))
diff --git a/stdlib/source/lux/macro/ast.lux b/stdlib/source/lux/macro/ast.lux
index 8976ca64d..821264c09 100644
--- a/stdlib/source/lux/macro/ast.lux
+++ b/stdlib/source/lux/macro/ast.lux
@@ -43,7 +43,7 @@
   [bool   Bool             #;BoolS]
   [nat    Nat              #;NatS]
   [int    Int              #;IntS]
-  [frac   Frac             #;FracS]
+  [deg   Deg             #;DegS]
   [real   Real             #;RealS]
   [char   Char             #;CharS]
   [text   Text             #;TextS]
@@ -73,7 +73,7 @@
       ([#;BoolS   Eq]
        [#;NatS    Eq]
        [#;IntS    Eq]
-       [#;FracS   Eq]
+       [#;DegS   Eq]
        [#;RealS   Eq]
        [#;CharS   char;Eq]
        [#;TextS   Eq]
@@ -110,7 +110,7 @@
     ([#;BoolS   Codec]
      [#;NatS    Codec]
      [#;IntS    Codec]
-     [#;FracS   Codec]
+     [#;DegS    Codec]
      [#;RealS   Codec]
      [#;CharS   char;Codec]
      [#;TextS   text;Codec]
diff --git a/stdlib/source/lux/macro/poly.lux b/stdlib/source/lux/macro/poly.lux
index ec4a87068..d194a540b 100644
--- a/stdlib/source/lux/macro/poly.lux
+++ b/stdlib/source/lux/macro/poly.lux
@@ -59,7 +59,7 @@
   [bool "Bool"]
   [nat  "Nat"]
   [int  "Int"]
-  [frac "Frac"]
+  [deg  "Deg"]
   [real "Real"]
   [char "Char"]
   [text "Text"]
@@ -78,7 +78,7 @@
                           [bool Bool]
                           [nat  Nat]
                           [int  Int]
-                          [frac Frac]
+                          [deg  Deg]
                           [real Real]
                           [char Char]
                           [text Text])]
diff --git a/stdlib/source/lux/macro/poly/eq.lux b/stdlib/source/lux/macro/poly/eq.lux
index dc37e0c9f..bdce71d50 100644
--- a/stdlib/source/lux/macro/poly/eq.lux
+++ b/stdlib/source/lux/macro/poly/eq.lux
@@ -50,7 +50,7 @@
                      [Bool poly;bool bool;Eq]
                      [Nat  poly;nat  number;Eq]
                      [Int  poly;int  number;Eq]
-                     [Frac poly;frac number;Eq]
+                     [Deg poly;deg number;Eq]
                      [Real poly;real number;Eq]
                      [Char poly;char char;Eq]
                      [Text poly;text text;Eq])]
diff --git a/stdlib/source/lux/macro/poly/text-encoder.lux b/stdlib/source/lux/macro/poly/text-encoder.lux
index 858abc208..c538844a7 100644
--- a/stdlib/source/lux/macro/poly/text-encoder.lux
+++ b/stdlib/source/lux/macro/poly/text-encoder.lux
@@ -51,7 +51,7 @@
                      [Bool poly;bool (:: bool;Codec encode)]
                      [Nat  poly;nat  (:: number;Codec encode)]
                      [Int  poly;int  (:: number;Codec encode)]
-                     [Frac poly;frac (:: number;Codec encode)]
+                     [Deg poly;deg (:: number;Codec encode)]
                      [Real poly;real (:: number;Codec encode)]
                      [Char poly;char (:: char;Codec encode)]
                      [Text poly;text (:: text;Codec encode)])]
diff --git a/stdlib/source/lux/macro/syntax.lux b/stdlib/source/lux/macro/syntax.lux
index 45aaee1bb..ba24b607b 100644
--- a/stdlib/source/lux/macro/syntax.lux
+++ b/stdlib/source/lux/macro/syntax.lux
@@ -92,7 +92,7 @@
 
 (do-template [    ]
   [(def: #export 
-     {#;doc (#;TextM ($_ Text/append "Parses the next "  " input AST."))}
+     {#;doc (#;TextA ($_ Text/append "Parses the next "  " input AST."))}
      (Syntax )
      (lambda [tokens]
        (case tokens
@@ -105,7 +105,7 @@
   [  bool  Bool   #;BoolS   bool;Eq "bool"]
   [   nat   Nat    #;NatS  number;Eq "nat"]
   [   int   Int    #;IntS  number;Eq "int"]
-  [  frac  Frac   #;FracS number;Eq "frac"]
+  [  deg  Deg   #;DegS number;Eq "deg"]
   [  real  Real   #;RealS number;Eq "real"]
   [  char  Char   #;CharS   char;Eq "char"]
   [  text  Text   #;TextS   text;Eq "text"]
@@ -164,7 +164,7 @@
 
 (do-template [  ]
   [(def: #export 
-     {#;doc (#;TextM ($_ Text/append "Parse a local "  " (a "  " that has no module prefix)."))}
+     {#;doc (#;TextA ($_ Text/append "Parse a local "  " (a "  " that has no module prefix)."))}
      (Syntax Text)
      (lambda [tokens]
        (case tokens
@@ -180,7 +180,7 @@
 
 (do-template [  ]
   [(def: #export ( p)
-     {#;doc (#;TextM ($_ Text/append "Parse inside the contents of a "  " as if they were the input ASTs."))}
+     {#;doc (#;TextA ($_ Text/append "Parse inside the contents of a "  " as if they were the input ASTs."))}
      (All [a]
        (-> (Syntax a) (Syntax a)))
      (lambda [tokens]
@@ -198,7 +198,7 @@
   )
 
 (def: #export (record p)
-  {#;doc (#;TextM ($_ Text/append "Parse inside the contents of a record as if they were the input ASTs."))}
+  {#;doc (#;TextA ($_ Text/append "Parse inside the contents of a record as if they were the input ASTs."))}
   (All [a]
     (-> (Syntax a) (Syntax a)))
   (lambda [tokens]
diff --git a/stdlib/source/lux/macro/syntax/common.lux b/stdlib/source/lux/macro/syntax/common.lux
index 72faa2ada..96203b4c2 100644
--- a/stdlib/source/lux/macro/syntax/common.lux
+++ b/stdlib/source/lux/macro/syntax/common.lux
@@ -105,13 +105,13 @@
 (def: list-meta^
   (Syntax (List AST))
   (s;form (do s;Monad
-            [_ (s;sample! (' #lux;ListM))]
+            [_ (s;sample! (' #lux;ListA))]
             (flat-list^ []))))
 
 (def: text-meta^
   (Syntax Text)
   (s;form (do s;Monad
-            [_ (s;sample! (' #lux;TextM))]
+            [_ (s;sample! (' #lux;TextA))]
             s;text)))
 
 (def: (find-def-args meta-data)
diff --git a/stdlib/source/lux/math.lux b/stdlib/source/lux/math.lux
index c1d855c8e..d5a03b421 100644
--- a/stdlib/source/lux/math.lux
+++ b/stdlib/source/lux/math.lux
@@ -57,6 +57,10 @@
   [radians "invokestatic:java.lang.Math:toRadians:double"]
   )
 
+(def: #export (square n)
+  (-> Real Real)
+  (r.* n n))
+
 (do-template [ ]
   [(def: #export ( n)
      (-> Real Real)
@@ -110,7 +114,7 @@
           (s/map ast;bool s;bool)
           (s/map ast;nat s;nat)
           (s/map ast;int s;int)
-          (s/map ast;frac s;frac)
+          (s/map ast;deg s;deg)
           (s/map ast;real s;real)
           (s/map ast;char s;char)
           (s/map ast;text s;text)
diff --git a/stdlib/source/lux/math/simple.lux b/stdlib/source/lux/math/simple.lux
index 111e5cc8c..f8b059794 100644
--- a/stdlib/source/lux/math/simple.lux
+++ b/stdlib/source/lux/math/simple.lux
@@ -46,7 +46,7 @@
       _
       (wrap raw-type))))
 
-(do-template [     ]
+(do-template [     ]
   [(syntax: #export ( [args ($_ s;alt
                                       (s;seq (s;alt s;symbol s;any)
                                              (s;some s;any))
@@ -58,7 +58,7 @@
      ##             (= ( 1.0 2.0)
      ##                ( 1.0 2.0))
      ##             (= ( .1 .2)
-     ##                ( .1 .2)))}
+     ##                ( .1 .2)))}
      (case args
        (+0 [(#;Left x) ys])
        (do @
@@ -72,8 +72,8 @@
                    (check;checks? Real =x)
                    (wrap (` ))
 
-                   (check;checks? Frac =x)
-                   (wrap (` ))
+                   (check;checks? Deg =x)
+                   (wrap (` ))
 
                    (compiler;fail (format "No operation for types: " (%type =x))))]
          (wrap (list (` ($_ (~ op) (~ (ast;symbol x)) (~@ ys))))))
@@ -96,21 +96,21 @@
                    (check;checks? (-> Real Real Real) =e)
                    (wrap (` ))
 
-                   (check;checks? (-> Frac Frac Frac) =e)
-                   (wrap (` ))
+                   (check;checks? (-> Deg Deg Deg) =e)
+                   (wrap (` ))
 
                    (compiler;fail (format "No operation for type: " (%type =e))))]
          (wrap (list op)))
        ))]
 
-  [+ ;;+ n.+ i.+ r.+ f.+]
-  [- ;;- n.- i.- r.- f.-]
-  [* ;;* n.* i.* r.* f.*]
-  [/ ;;/ n./ i./ r./ f./]
-  [% ;;% n.% i.% r.% f.%]
+  [+ ;;+ n.+ i.+ r.+ d.+]
+  [- ;;- n.- i.- r.- d.-]
+  [* ;;* n.* i.* r.* d.*]
+  [/ ;;/ n./ i./ r./ d./]
+  [% ;;% n.% i.% r.% d.%]
   )
 
-(do-template [     ]
+(do-template [     ]
   [(syntax: #export ( [args ($_ s;alt
                                       (s;seq (s;alt s;symbol s;any)
                                              (s;some s;any))
@@ -122,7 +122,7 @@
      ##             (= ( 1.0 2.0)
      ##                ( 1.0 2.0))
      ##             (= ( .1 .2)
-     ##                ( .1 .2)))}
+     ##                ( .1 .2)))}
      (case args
        (+0 [(#;Left x) ys])
        (do @
@@ -136,8 +136,8 @@
                    (check;checks? Real =x)
                    (wrap (` ))
 
-                   (check;checks? Frac =x)
-                   (wrap (` ))
+                   (check;checks? Deg =x)
+                   (wrap (` ))
 
                    (compiler;fail (format "No operation for types: " (%type =x))))]
          (wrap (list (` ($_ (~ op) (~ (ast;symbol x)) (~@ ys))))))
@@ -160,18 +160,18 @@
                    (check;checks? (-> Real Real Bool) =e)
                    (wrap (` ))
 
-                   (check;checks? (-> Frac Frac Bool) =e)
-                   (wrap (` ))
+                   (check;checks? (-> Deg Deg Bool) =e)
+                   (wrap (` ))
 
                    (compiler;fail (format "No operation for type: " (%type =e))))]
          (wrap (list op)))
        ))]
 
-  [=  ;;=  n.=  i.=  r.=  f.=]
-  [<  ;;<  n.<  i.<  r.<  f.<]
-  [<= ;;<= n.<= i.<= r.<= f.<=]
-  [>  ;;>  n.>  i.>  r.>  f.>]
-  [>= ;;>= n.>= i.>= r.>= f.>=]
+  [=  ;;=  n.=  i.=  r.=  d.=]
+  [<  ;;<  n.<  i.<  r.<  d.<]
+  [<= ;;<= n.<= i.<= r.<= d.<=]
+  [>  ;;>  n.>  i.>  r.>  d.>]
+  [>= ;;>= n.>= i.>= r.>= d.>=]
   )
 
 (do-template [   ]
diff --git a/stdlib/source/lux/random.lux b/stdlib/source/lux/random.lux
index 802dbfae6..195255643 100644
--- a/stdlib/source/lux/random.lux
+++ b/stdlib/source/lux/random.lux
@@ -100,9 +100,9 @@
               int-to-real
               (r./ (|> +1 (bit;<< +53) nat-to-int int-to-real))))))
 
-(def: #export frac
-  (Random Frac)
-  (:: Monad map real-to-frac real))
+(def: #export deg
+  (Random Deg)
+  (:: Monad map real-to-deg real))
 
 (def: #export char
   (Random Char)
diff --git a/stdlib/source/lux/regex.lux b/stdlib/source/lux/regex.lux
deleted file mode 100644
index 5684a4465..000000000
--- a/stdlib/source/lux/regex.lux
+++ /dev/null
@@ -1,491 +0,0 @@
-##  Copyright (c) Eduardo Julian. All rights reserved.
-##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
-##  If a copy of the MPL was not distributed with this file,
-##  You can obtain one at http://mozilla.org/MPL/2.0/.
-
-(;module:
-  lux
-  (lux (control monad)
-       (data [char]
-             [text]
-             text/format
-             [number "Int/" Codec]
-             [product]
-             (struct [list "" Fold "List/" Monad]))
-       [compiler #- run]
-       (macro [ast]
-              [syntax #+ syntax:])
-       ["&" lexer #+ Lexer Monad]))
-
-## [Utils]
-(def: #hidden (->Text lexer^)
-  (-> (Lexer Char) (Lexer Text))
-  (do Monad
-    [output lexer^]
-    (wrap (char;as-text output))))
-
-(def: regex-char^
-  (Lexer Char)
-  (&;none-of "\\.|&()[]{}"))
-
-(def: escaped-char^
-  (Lexer Char)
-  (do Monad
-    [? (&;opt (&;char #"\\"))
-     char (case ?
-            (#;Some _) &;any
-            #;None     regex-char^)]
-    (wrap char)))
-
-(def: (local^ state lexer)
-  (All [a] (-> Text (Lexer a) (Lexer a)))
-  (lambda [old-state]
-    (case (lexer state)
-      (#;Left error)
-      (#;Left error)
-
-      (#;Right [_ value])
-      (#;Right [old-state value]))))
-
-(def: #hidden (refine^ refinement^ base^)
-  (All [a] (-> (Lexer a) (Lexer Text) (Lexer Text)))
-  (do Monad
-    [output base^
-     _ (local^ output refinement^)]
-    (wrap output)))
-
-(def: #hidden word^
-  (Lexer Char)
-  (&;either &;alpha-num
-            (&;char #"_")))
-
-(def: #hidden (join-text^ part^)
-  (-> (Lexer (List Text)) (Lexer Text))
-  (do Monad
-    [parts part^]
-    (wrap (text;join-with "" parts))))
-
-(def: identifier-char^
-  (Lexer Char)
-  (&;none-of "[]{}()s\"#;<>"))
-
-(def: identifier-part^
-  (Lexer Text)
-  (do Monad
-    [head (refine^ (&;not &;digit)
-                   (->Text identifier-char^))
-     tail (&;some' identifier-char^)]
-    (wrap (format head tail))))
-
-(def: (identifier^ current-module)
-  (-> Text (Lexer Ident))
-  (do Monad
-    []
-    ($_ &;either
-        (&;seq (wrap current-module) (&;_& (&;text ";;") identifier-part^))
-        (&;seq identifier-part^ (&;_& (&;text ";") identifier-part^))
-        (&;seq (wrap "lux") (&;_& (&;text ";") identifier-part^))
-        (&;seq (wrap "") identifier-part^))))
-
-(def: (re-var^ current-module)
-  (-> Text (Lexer AST))
-  (do Monad
-    [ident (&;enclosed ["\\@<" ">"] (identifier^ current-module))]
-    (wrap (` (: (Lexer Text) (~ (ast;symbol ident)))))))
-
-(def: re-char-range^
-  (Lexer AST)
-  (do Monad
-    [from regex-char^
-     _ (&;char #"-")
-     to regex-char^]
-    (wrap (` (&;char-range (~ (ast;char from)) (~ (ast;char to)))))))
-
-(def: re-char^
-  (Lexer AST)
-  (do Monad
-    [char escaped-char^]
-    (wrap (` (&;char (~ (ast;char char)))))))
-
-(def: re-char+^
-  (Lexer AST)
-  (do Monad
-    [base re-char^]
-    (wrap (` (->Text (~ base))))))
-
-(def: re-char-options^
-  (Lexer AST)
-  (do Monad
-    [options (&;many' escaped-char^)]
-    (wrap (` (&;one-of (~ (ast;text options)))))))
-
-(def: re-user-class^'
-  (Lexer AST)
-  (do Monad
-    [negate? (&;opt (&;char #"^"))
-     parts (&;many ($_ &;either
-                       re-char-range^
-                       re-char-options^))]
-    (wrap (case negate?
-            (#;Some _) (` (->Text (&;not ($_ &;either (~@ parts)))))
-            #;None     (` (->Text ($_ &;either (~@ parts))))))))
-
-(def: re-user-class^
-  (Lexer AST)
-  (do Monad
-    [_ (wrap [])
-     init re-user-class^'
-     rest (&;some (&;_& (&;text "&&") (&;enclosed ["[" "]"] re-user-class^')))]
-    (wrap (fold (lambda [refinement base]
-                  (` (refine^ (~ refinement) (~ base))))
-                init
-                rest))))
-
-(def: #hidden blank^
-  (Lexer Char)
-  (&;one-of " \t"))
-
-(def: #hidden ascii^
-  (Lexer Char)
-  (&;char-range #"\u0000" #"\u007F"))
-
-(def: #hidden control^
-  (Lexer Char)
-  (&;either (&;char-range #"\u0000" #"\u001F")
-            (&;char #"\u007F")))
-
-(def: #hidden punct^
-  (Lexer Char)
-  (&;one-of "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"))
-
-(def: #hidden graph^
-  (Lexer Char)
-  (&;either punct^ &;alpha-num))
-
-(def: #hidden print^
-  (Lexer Char)
-  (&;either graph^
-            (&;char #"\u0020")))
-
-(def: re-system-class^
-  (Lexer AST)
-  (do Monad
-    []
-    ($_ &;either
-        (&;_& (&;char #".") (wrap (` (->Text &;any))))
-        (&;_& (&;text "\\d") (wrap (` (->Text &;digit))))
-        (&;_& (&;text "\\D") (wrap (` (->Text (&;not &;digit)))))
-        (&;_& (&;text "\\s") (wrap (` (->Text  &;space))))
-        (&;_& (&;text "\\S") (wrap (` (->Text (&;not &;space)))))
-        (&;_& (&;text "\\w") (wrap (` (->Text word^))))
-        (&;_& (&;text "\\W") (wrap (` (->Text (&;not word^)))))
-        (&;_& (&;text "\\d") (wrap (` (->Text &;digit))))
-
-        (&;_& (&;text "\\p{Lower}") (wrap (` (->Text &;lower))))
-        (&;_& (&;text "\\p{Upper}") (wrap (` (->Text &;upper))))
-        (&;_& (&;text "\\p{Alpha}") (wrap (` (->Text &;alpha))))
-        (&;_& (&;text "\\p{Digit}") (wrap (` (->Text &;digit))))
-        (&;_& (&;text "\\p{Alnum}") (wrap (` (->Text &;alpha-num))))
-        (&;_& (&;text "\\p{Space}") (wrap (` (->Text &;space))))
-        (&;_& (&;text "\\p{HexDigit}") (wrap (` (->Text &;hex-digit))))
-        (&;_& (&;text "\\p{OctDigit}") (wrap (` (->Text &;oct-digit))))
-        (&;_& (&;text "\\p{Blank}") (wrap (` (->Text blank^))))
-        (&;_& (&;text "\\p{ASCII}") (wrap (` (->Text ascii^))))
-        (&;_& (&;text "\\p{Contrl}") (wrap (` (->Text control^))))
-        (&;_& (&;text "\\p{Punct}") (wrap (` (->Text punct^))))
-        (&;_& (&;text "\\p{Graph}") (wrap (` (->Text graph^))))
-        (&;_& (&;text "\\p{Print}") (wrap (` (->Text print^))))
-        )))
-
-(def: re-class^
-  (Lexer AST)
-  (&;either re-system-class^
-            (&;enclosed ["[" "]"] re-user-class^)))
-
-(def: int^
-  (Lexer Int)
-  (&;codec number;Codec (&;many' &;digit)))
-
-(def: re-back-reference^
-  (Lexer AST)
-  (&;either (do Monad
-              [_ (&;char #"\\")
-               id int^]
-              (wrap (` (&;text (~ (ast;symbol ["" (Int/encode id)]))))))
-            (do Monad
-              [_ (&;text "\\k<")
-               captured-name identifier-part^
-               _ (&;text ">")]
-              (wrap (` (&;text (~ (ast;symbol ["" captured-name]))))))))
-
-(def: (re-simple^ current-module)
-  (-> Text (Lexer AST))
-  ($_ &;either
-      re-class^
-      (re-var^ current-module)
-      re-back-reference^
-      re-char+^
-      ))
-
-(def: (re-simple-quantified^ current-module)
-  (-> Text (Lexer AST))
-  (do Monad
-    [base (re-simple^ current-module)
-     quantifier (&;one-of "?*+")]
-    (case quantifier
-      #"?"
-      (wrap (` (&;default "" (~ base))))
-      
-      #"*"
-      (wrap (` (join-text^ (&;some (~ base)))))
-      
-      _
-      (wrap (` (join-text^ (&;many (~ base)))))
-      )))
-
-(def: (re-counted-quantified^ current-module)
-  (-> Text (Lexer AST))
-  (do Monad
-    [base (re-simple^ current-module)]
-    (&;enclosed ["{" "}"]
-                ($_ &;either
-                    (do @
-                      [[from to] (&;seq int^ (&;_& (&;char #",") int^))]
-                      (wrap (` (join-text^ (&;between (~ (ast;nat (int-to-nat from)))
-                                                      (~ (ast;nat (int-to-nat to)))
-                                                      (~ base))))))
-                    (do @
-                      [limit (&;_& (&;char #",") int^)]
-                      (wrap (` (join-text^ (&;at-most (~ (ast;nat (int-to-nat limit))) (~ base))))))
-                    (do @
-                      [limit (&;&_ int^ (&;char #","))]
-                      (wrap (` (join-text^ (&;at-least (~ (ast;nat (int-to-nat limit))) (~ base))))))
-                    (do @
-                      [limit int^]
-                      (wrap (` (join-text^ (&;exactly (~ (ast;nat (int-to-nat limit))) (~ base))))))))))
-
-(def: (re-quantified^ current-module)
-  (-> Text (Lexer AST))
-  (&;either (re-simple-quantified^ current-module)
-            (re-counted-quantified^ current-module)))
-
-(def: (re-complex^ current-module)
-  (-> Text (Lexer AST))
-  ($_ &;either
-      (re-quantified^ current-module)
-      (re-simple^ current-module)))
-
-(def: #hidden _Text/append_
-  (-> Text Text Text)
-  (:: text;Monoid append))
-
-(type: Re-Group
-  #Non-Capturing
-  (#Capturing [(Maybe Text) Nat]))
-
-(def: (re-sequential^ capturing? re-scoped^ current-module)
-  (-> Bool
-      (-> Text (Lexer [Re-Group AST]))
-      Text
-      (Lexer [Nat AST]))
-  (do Monad
-    [parts (&;many (&;alt (re-complex^ current-module)
-                          (re-scoped^ current-module)))
-     #let [g!total (ast;symbol ["" "0total"])
-           g!temp (ast;symbol ["" "0temp"])
-           [_ names steps] (fold (: (-> (Either AST [Re-Group AST])
-                                        [Int (List AST) (List (List AST))]
-                                        [Int (List AST) (List (List AST))])
-                                    (lambda [part [idx names steps]]
-                                      (case part
-                                        (^or (#;Left complex) (#;Right [#Non-Capturing complex]))
-                                        [idx
-                                         names
-                                         (list& (list g!temp complex
-                                                      (' #let) (` [(~ g!total) (_Text/append_ (~ g!total) (~ g!temp))]))
-                                                steps)]
-                                        
-                                        (#;Right [(#Capturing [?name num-captures]) scoped])
-                                        (let [[idx! name!] (case ?name
-                                                             (#;Some _name)
-                                                             [idx (ast;symbol ["" _name])]
-
-                                                             #;None
-                                                             [(i.inc idx) (ast;symbol ["" (Int/encode idx)])])
-                                              access (if (n.> +0 num-captures)
-                                                       (` (product;left (~ name!)))
-                                                       name!)]
-                                          [idx!
-                                           (list& name! names)
-                                           (list& (list name! scoped
-                                                        (' #let) (` [(~ g!total) (_Text/append_ (~ g!total) (~ access))]))
-                                                  steps)])
-                                        )))
-                                 [0
-                                  (: (List AST) (list))
-                                  (: (List (List AST)) (list))]
-                                 parts)]]
-    (wrap [(if capturing?
-             (list;size names)
-             +0)
-           (` (do Monad
-                [(~ (' #let)) [(~ g!total) ""]
-                 (~@ (|> steps list;reverse List/join))]
-                ((~ (' wrap)) [(~ g!total) (~@ (list;reverse names))])))])
-    ))
-
-(def: #hidden (unflatten^ lexer)
-  (-> (Lexer Text) (Lexer [Text Unit]))
-  (&;seq lexer (:: Monad wrap [])))
-
-(def: #hidden (|||^ left right)
-  (All [l r] (-> (Lexer [Text l]) (Lexer [Text r]) (Lexer [Text (| l r)])))
-  (lambda [input]
-    (case (left input)
-      (#;Right [input' [lt lv]])
-      (#;Right [input' [lt (+0 lv)]])
-
-      (#;Left _)
-      (case (right input)
-        (#;Right [input' [rt rv]])
-        (#;Right [input' [rt (+1 rv)]])
-
-        (#;Left error)
-        (#;Left error)))))
-
-(def: #hidden (|||_^ left right)
-  (All [l r] (-> (Lexer [Text l]) (Lexer [Text r]) (Lexer Text)))
-  (lambda [input]
-    (case (left input)
-      (#;Right [input' [lt lv]])
-      (#;Right [input' lt])
-
-      (#;Left _)
-      (case (right input)
-        (#;Right [input' [rt rv]])
-        (#;Right [input' rt])
-
-        (#;Left error)
-        (#;Left error)))))
-
-(def: (prep-alternative [num-captures alt])
-  (-> [Nat AST] AST)
-  (if (n.> +0 num-captures)
-    alt
-    (` (unflatten^ (~ alt)))))
-
-(def: (re-alternative^ capturing? re-scoped^ current-module)
-  (-> Bool
-      (-> Text (Lexer [Re-Group AST]))
-      Text
-      (Lexer [Nat AST]))
-  (do Monad
-    [#let [sub^ (re-sequential^ capturing? re-scoped^ current-module)]
-     head sub^
-     tail (&;some (&;_& (&;char #"|") sub^))
-     #let [g!op (if capturing?
-                  (` |||^)
-                  (` |||_^))]]
-    (if (list;empty? tail)
-      (wrap head)
-      (wrap [(fold n.max (product;left head) (List/map product;left tail))
-             (` ($_ (~ g!op) (~ (prep-alternative head)) (~@ (List/map prep-alternative tail))))]))))
-
-(def: (re-scoped^ current-module)
-  (-> Text (Lexer [Re-Group AST]))
-  ($_ &;either
-      (do Monad
-        [_ (&;text "(?:")
-         [_ scoped] (re-alternative^ false re-scoped^ current-module)
-         _ (&;char #")")]
-        (wrap [#Non-Capturing scoped]))
-      (do Monad
-        [complex (re-complex^ current-module)]
-        (wrap [#Non-Capturing complex]))
-      (do Monad
-        [_ (&;text "(?<")
-         captured-name identifier-part^
-         _ (&;text ">")
-         [num-captures pattern] (re-alternative^ true re-scoped^ current-module)
-         _ (&;char #")")]
-        (wrap [(#Capturing [(#;Some captured-name) num-captures]) pattern]))
-      (do Monad
-        [_ (&;char #"(")
-         [num-captures pattern] (re-alternative^ true re-scoped^ current-module)
-         _ (&;char #")")]
-        (wrap [(#Capturing [#;None num-captures]) pattern]))))
-
-(def: (regex^ current-module)
-  (-> Text (Lexer AST))
-  (:: Monad map product;right (re-alternative^ true re-scoped^ current-module)))
-
-## [Syntax]
-(syntax: #export (regex [pattern syntax;text])
-  {#;doc (doc "Create lexers using regular-expression syntax."
-              "For example:"
-              
-              "Literals"
-              (regex "a")
-              
-              "Wildcards"
-              (regex ".")
-              
-              "Escaping"
-              (regex "\\.")
-              
-              "Character classes"
-              (regex "\\d")
-              (regex "\\p{Lower}")
-              (regex "[abc]")
-              (regex "[a-z]")
-              (regex "[a-zA-Z]")
-              (regex "[a-z&&[def]]")
-              
-              "Negation"
-              (regex "[^abc]")
-              (regex "[^a-z]")
-              (regex "[^a-zA-Z]")
-              (regex "[a-z&&[^bc]]")
-              (regex "[a-z&&[^m-p]]")
-              
-              "Combinations"
-              (regex "aa")
-              (regex "a?")
-              (regex "a*")
-              (regex "a+")
-              
-              "Specific amounts"
-              (regex "a{2}")
-              
-              "At least"
-              (regex "a{1,}")
-              
-              "At most"
-              (regex "a{,1}")
-              
-              "Between"
-              (regex "a{1,2}")
-              
-              "Groups"
-              (regex "a(.)c")
-              (regex "a(b+)c")
-              (regex "(\\d{3})-(\\d{3})-(\\d{4})")
-              (regex "(\\d{3})-(?:\\d{3})-(\\d{4})")
-              (regex "(?\\d{3})-\\k-(\\d{4})")
-              (regex "(?\\d{3})-\\k-(\\d{4})-\\0")
-              (regex "(\\d{3})-((\\d{3})-(\\d{4}))")
-              
-              "Alternation"
-              (regex "a|b")
-              (regex "a(.)(.)|b(.)(.)")
-              )}
-  (do @
-    [current-module compiler;current-module-name]
-    (case (&;run pattern
-                 (&;&_ (regex^ current-module) &;end))
-      (#;Left error)
-      (compiler;fail error)
-
-      (#;Right regex)
-      (wrap (list regex))
-      )))
diff --git a/stdlib/source/lux/test.lux b/stdlib/source/lux/test.lux
index e7012f06e..9524a2168 100644
--- a/stdlib/source/lux/test.lux
+++ b/stdlib/source/lux/test.lux
@@ -247,7 +247,7 @@
                body)]
     (with-gensyms [g!test]
       (wrap (list (` (def: #export (~ g!test)
-                       {#;;test (#;TextM (~ description))}
+                       {#;;test (#;TextA (~ description))}
                        (IO Test)
                        (io (~ body)))))))))
 
diff --git a/stdlib/test/test/lux.lux b/stdlib/test/test/lux.lux
index 6c1ea6f4b..cd394ac76 100644
--- a/stdlib/test/test/lux.lux
+++ b/stdlib/test/test/lux.lux
@@ -75,7 +75,7 @@
   ["Int"  R;int  i.= i.< i.> i.<= i.>= i.min i.max]
   ["Nat"  R;nat  n.= n.< n.> n.<= n.>= n.min n.max]
   ["Real" R;real r.= r.< r.> r.<= r.>= r.min r.max]
-  ["Frac" R;frac f.= f.< f.> f.<= f.>= f.min f.max]
+  ["Deg" R;deg d.= d.< d.> d.<= d.>= d.min d.max]
   )
 
 (do-template [category rand-gen = + - * / <%> > <0> <1>  %x  ]
@@ -97,10 +97,10 @@
    (test: (format "[" category "] " "Multiplicative identity")
      [x rand-gen]
      (assert ""
-             ## Skip this test for Frac
-             ## because Frac division loses the last
+             ## Skip this test for Deg
+             ## because Deg division loses the last
              ## 32 bits of precision.
-             (or (T/= "Frac" category)
+             (or (T/= "Deg" category)
                  (and (|> x (* <1>) (= x))
                       (|> x (/ <1>) (= x))))))
 
@@ -112,10 +112,10 @@
       #let [r (<%> y x)
             x' (- r x)]]
      (assert ""
-             ## Skip this test for Frac
-             ## because Frac division loses the last
+             ## Skip this test for Deg
+             ## because Deg division loses the last
              ## 32 bits of precision.
-             (or (T/= "Frac" category)
+             (or (T/= "Deg" category)
                  (or (> x' y)
                      (|> x' (/ y) (* y) (= x'))))
              ))]
@@ -123,7 +123,7 @@
   ["Nat"  R;nat  n.= n.+ n.- n.* n./ n.% n.> +0  +1                                  +1000000                             %n (n.% +1000) id]
   ["Int"  R;int  i.= i.+ i.- i.* i./ i.% i.>  0   1                                   1000000                             %i (i.%  1000) id]
   ["Real" R;real r.= r.+ r.- r.* r./ r.% r.>  0.0 1.0                                 1000000.0                           %r id          math;floor]
-  ["Frac" R;frac f.= f.+ f.- f.* f./ f.% f.>  .0  (_lux_proc ["frac" "max-value"] []) (_lux_proc ["frac" "max-value"] []) %f id          id]
+  ["Deg" R;deg d.= d.+ d.- d.* d./ d.% d.>  .0  (_lux_proc ["deg" "max-value"] []) (_lux_proc ["deg" "max-value"] []) %f id          id]
   )
 
 (do-template [category rand-gen -> <- =  %a %z]
@@ -137,7 +137,7 @@
   ["Nat->Int"  R;nat  nat-to-int  int-to-nat  n.= (n.% +1000000)  %n %i]
   ["Int->Real" R;int  int-to-real real-to-int i.= (i.%   1000000)  %i %r]
   ["Real->Int" R;real real-to-int int-to-real r.= math;floor       %r %i]
-  ## [R;real real-to-frac frac-to-real r.= (r.% 1.0) %r %f]
+  ## [R;real real-to-deg deg-to-real r.= (r.% 1.0) %r %f]
   )
 
 (test: "Simple macros and constructs"
diff --git a/stdlib/test/test/lux/data/number.lux b/stdlib/test/test/lux/data/number.lux
index 20d72adf6..8b7267444 100644
--- a/stdlib/test/test/lux/data/number.lux
+++ b/stdlib/test/test/lux/data/number.lux
@@ -26,7 +26,7 @@
   ["Nat"  R;nat  Eq  Ord]
   ["Int"  R;int  Eq  Ord]
   ["Real" R;real Eq Ord]
-  ["Frac" R;frac Eq Ord]
+  ["Deg" R;deg Eq Ord]
   )
 
 (do-template [category rand-gen ]
@@ -39,14 +39,14 @@
                          (not (= x (negate x))))
                      (= x (negate (negate x)))
                      ## There is loss of precision when multiplying
-                     (or (Text/= "Frac" category)
+                     (or (Text/= "Deg" category)
                          (= x (* (signum x)
                                  (abs x)))))))]
 
   ## ["Nat"  R;nat  Number]
   ["Int"  R;int  Number]
   ["Real" R;real Number]
-  ["Frac" R;frac Number]
+  ["Deg" R;deg Number]
   )
 
 (do-template [category rand-gen  ]
@@ -79,7 +79,7 @@
   ["Int"  R;int  Number  Bounded  (lambda [_] true)]
   ## Both min and max values will be positive (thus, greater than zero)
   ["Real" R;real Number Bounded (r.> 0.0)]
-  ["Frac" R;frac Number Bounded (lambda [_] true)]
+  ["Deg" R;deg Number Bounded (lambda [_] true)]
   )
 
 (do-template [category rand-gen    ]
@@ -104,10 +104,10 @@
   ["Real/Mul" R;real Number Mul@Monoid (r.% 1000.0) (r.> 0.0)]
   ["Real/Min" R;real Number Min@Monoid (r.% 1000.0) (r.> 0.0)]
   ["Real/Max" R;real Number Max@Monoid (r.% 1000.0) (r.> 0.0)]
-  ["Frac/Add" R;frac Number Add@Monoid (f.% .125)   (lambda [_] true)]
-  ## ["Frac/Mul" R;frac Number Mul@Monoid (f.% .125)   (lambda [_] true)]
-  ["Frac/Min" R;frac Number Min@Monoid (f.% .125)   (lambda [_] true)]
-  ["Frac/Max" R;frac Number Max@Monoid (f.% .125)   (lambda [_] true)]
+  ["Deg/Add" R;deg Number Add@Monoid (d.% .125)   (lambda [_] true)]
+  ## ["Deg/Mul" R;deg Number Mul@Monoid (d.% .125)   (lambda [_] true)]
+  ["Deg/Min" R;deg Number Min@Monoid (d.% .125)   (lambda [_] true)]
+  ["Deg/Max" R;deg Number Max@Monoid (d.% .125)   (lambda [_] true)]
   )
 
 (do-template [   ]
@@ -126,7 +126,7 @@
   ["Nat"  R;nat  Number  Codec]
   ["Int"  R;int  Number  Codec]
   ["Real" R;real Number Codec]
-  ["Frac" R;frac Number Codec]
+  ["Deg" R;deg Number Codec]
   )
 
 (do-template [   ]
diff --git a/stdlib/test/test/lux/data/struct/tree.lux b/stdlib/test/test/lux/data/struct/tree.lux
deleted file mode 100644
index 91a81355e..000000000
--- a/stdlib/test/test/lux/data/struct/tree.lux
+++ /dev/null
@@ -1,40 +0,0 @@
-##  Copyright (c) Eduardo Julian. All rights reserved.
-##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
-##  If a copy of the MPL was not distributed with this file,
-##  You can obtain one at http://mozilla.org/MPL/2.0/.
-
-(;module:
-  lux
-  (lux (codata [io])
-       (control monad)
-       (data (struct ["&" tree]
-                     [list "List/" Monad])
-             [number])
-       ["R" random]
-       pipe)
-  lux/test)
-
-(def: gen-nat
-  (R;Random Nat)
-  (|> R;nat
-      (:: R;Monad map (n.% +100))))
-
-(test: "Trees"
-  [leaf (:: @ map &;leaf R;nat)
-   branchS gen-nat
-   branchV R;nat
-   branchC (R;list branchS R;nat)
-   #let [branch (&;branch branchV (List/map &;leaf branchC))]
-   #let [(^open "&/") (&;Eq number;Eq)
-         (^open "List/") (list;Eq number;Eq)]]
-  ($_ seq
-      (assert "Can compare trees for equality."
-              (and (&/= leaf leaf)
-                   (&/= branch branch)
-                   (not (&/= leaf branch))
-                   (not (&/= leaf (&;branch branchV (List/map &;leaf (list;reverse branchC)))))))
-
-      (assert "Can flatten a tree to get all the nodes as a flat tree."
-              (List/= (list& branchV branchC)
-                      (&;flatten branch)))
-      ))
diff --git a/stdlib/test/test/lux/data/struct/tree/rose.lux b/stdlib/test/test/lux/data/struct/tree/rose.lux
new file mode 100644
index 000000000..21592aba9
--- /dev/null
+++ b/stdlib/test/test/lux/data/struct/tree/rose.lux
@@ -0,0 +1,40 @@
+##  Copyright (c) Eduardo Julian. All rights reserved.
+##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+##  If a copy of the MPL was not distributed with this file,
+##  You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(;module:
+  lux
+  (lux (codata [io])
+       (control monad)
+       (data (struct (tree ["&" rose])
+                     [list "List/" Monad])
+             [number])
+       ["R" random]
+       pipe)
+  lux/test)
+
+(def: gen-nat
+  (R;Random Nat)
+  (|> R;nat
+      (:: R;Monad map (n.% +100))))
+
+(test: "Trees"
+  [leaf (:: @ map &;leaf R;nat)
+   branchS gen-nat
+   branchV R;nat
+   branchC (R;list branchS R;nat)
+   #let [branch (&;branch branchV (List/map &;leaf branchC))]
+   #let [(^open "&/") (&;Eq number;Eq)
+         (^open "List/") (list;Eq number;Eq)]]
+  ($_ seq
+      (assert "Can compare trees for equality."
+              (and (&/= leaf leaf)
+                   (&/= branch branch)
+                   (not (&/= leaf branch))
+                   (not (&/= leaf (&;branch branchV (List/map &;leaf (list;reverse branchC)))))))
+
+      (assert "Can flatten a tree to get all the nodes as a flat tree."
+              (List/= (list& branchV branchC)
+                      (&;flatten branch)))
+      ))
diff --git a/stdlib/test/test/lux/data/struct/tree/zipper.lux b/stdlib/test/test/lux/data/struct/tree/zipper.lux
new file mode 100644
index 000000000..f2d7fe708
--- /dev/null
+++ b/stdlib/test/test/lux/data/struct/tree/zipper.lux
@@ -0,0 +1,128 @@
+##  Copyright (c) Eduardo Julian. All rights reserved.
+##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+##  If a copy of the MPL was not distributed with this file,
+##  You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(;module:
+  lux
+  (lux (codata [io])
+       (control monad)
+       (data (struct [list "List/" Fold Functor]
+                     (tree ["&" zipper]
+                           [rose]))
+             [text "Text/" Monoid]
+             text/format
+             [number])
+       (codata function)
+       ["R" random]
+       pipe)
+  lux/test)
+
+(def: gen-tree
+  (R;Random (rose;Tree Nat))
+  (R;rec (lambda [gen-tree]
+           (do R;Monad
+             ## Each branch can have, at most, 1 child.
+             [size (|> R;nat (:: @ map (n.% +2)))]
+             (R;seq R;nat
+                    (R;list size gen-tree))))))
+
+(def: (to-end zipper)
+  (All [a] (-> (&;Zipper a) (&;Zipper a)))
+  (loop [zipper zipper]
+    (if (&;end? zipper)
+      zipper
+      (recur (&;next zipper)))))
+
+(test: "Zippers"
+  [sample gen-tree
+   new-val R;nat
+   pre-val R;nat
+   post-val R;nat
+   #let [(^open "Tree/") (rose;Eq number;Eq)
+         (^open "List/") (list;Eq number;Eq)]]
+  ($_ seq
+      (assert "Trees can be converted to/from zippers."
+              (|> sample
+                  &;from-tree &;to-tree
+                  (Tree/= sample)))
+
+      (assert "Creating a zipper gives you a root node."
+              (|> sample &;from-tree &;root?))
+      
+      (assert "Can move down inside branches. Can move up from lower nodes."
+              (let [zipper (&;from-tree sample)]
+                (if (&;branch? zipper)
+                  (let [child (|> zipper &;down)]
+                    (and (not (Tree/= sample (&;to-tree child)))
+                         (|> child &;parent (default (undefined)) (is zipper))
+                         (|> child &;up (is zipper) not)
+                         (|> child &;root (is zipper) not)))
+                  (and (&;leaf? zipper)
+                       (|> zipper (&;prepend-child new-val) &;branch?)))))
+
+      (assert "Can prepend and append children."
+              (let [zipper (&;from-tree sample)]
+                (if (&;branch? zipper)
+                  (let [mid-val (|> zipper &;down &;value)
+                        zipper (|> zipper
+                                   (&;prepend-child pre-val)
+                                   (&;append-child post-val))]
+                    (and (|> zipper &;down &;value (is pre-val))
+                         (|> zipper &;down &;right &;value (is mid-val))
+                         (|> zipper &;down &;right &;right &;value (is post-val))
+                         (|> zipper &;down &;rightmost &;leftmost &;value (is pre-val))
+                         (|> zipper &;down &;right &;left &;value (is pre-val))
+                         (|> zipper &;down &;rightmost &;value (is post-val))))
+                  true)))
+
+      (assert "Can insert children around a node (unless it's root)."
+              (let [zipper (&;from-tree sample)]
+                (if (&;branch? zipper)
+                  (let [mid-val (|> zipper &;down &;value)
+                        zipper (|> zipper
+                                   &;down
+                                   (&;insert-left pre-val)
+                                   (default (undefined))
+                                   (&;insert-right post-val)
+                                   (default (undefined))
+                                   &;up)]
+                    (and (|> zipper &;down &;value (is pre-val))
+                         (|> zipper &;down &;right &;value (is mid-val))
+                         (|> zipper &;down &;right &;right &;value (is post-val))
+                         (|> zipper &;down &;rightmost &;leftmost &;value (is pre-val))
+                         (|> zipper &;down &;right &;left &;value (is pre-val))
+                         (|> zipper &;down &;rightmost &;value (is post-val))))
+                  (and (|> zipper (&;insert-left pre-val) (case> (#;Some _) false
+                                                                 #;None     true))
+                       (|> zipper (&;insert-right post-val) (case> (#;Some _) false
+                                                                   #;None     true))))))
+      
+      (assert "Can set and update the value of a node."
+              (|> sample &;from-tree (&;set new-val) &;value (n.= new-val)))
+
+      (assert "Zipper traversal follows the outline of the tree depth-first."
+              (List/= (rose;flatten sample)
+                      (loop [zipper (&;from-tree sample)]
+                        (if (&;end? zipper)
+                          (list (&;value zipper))
+                          (#;Cons (&;value zipper)
+                                  (recur (&;next zipper)))))))
+
+      (assert "Backwards zipper traversal yield reverse tree flatten."
+              (List/= (list;reverse (rose;flatten sample))
+                      (loop [zipper (to-end (&;from-tree sample))]
+                        (if (&;root? zipper)
+                          (list (&;value zipper))
+                          (#;Cons (&;value zipper)
+                                  (recur (&;prev zipper)))))))
+
+      (assert "Can remove nodes (except root nodes)."
+              (let [zipper (&;from-tree sample)]
+                (if (&;branch? zipper)
+                  (and (|> zipper &;down &;root? not)
+                       (|> zipper &;down &;remove (case> #;None false
+                                                         (#;Some node) (&;root? node))))
+                  (|> zipper &;remove (case> #;None     true
+                                             (#;Some _) false)))))
+      ))
diff --git a/stdlib/test/test/lux/data/struct/zipper.lux b/stdlib/test/test/lux/data/struct/zipper.lux
deleted file mode 100644
index 37ada2859..000000000
--- a/stdlib/test/test/lux/data/struct/zipper.lux
+++ /dev/null
@@ -1,128 +0,0 @@
-##  Copyright (c) Eduardo Julian. All rights reserved.
-##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
-##  If a copy of the MPL was not distributed with this file,
-##  You can obtain one at http://mozilla.org/MPL/2.0/.
-
-(;module:
-  lux
-  (lux (codata [io])
-       (control monad)
-       (data (struct ["&" zipper]
-                     [tree]
-                     [list "List/" Fold Functor])
-             [text "Text/" Monoid]
-             text/format
-             [number])
-       (codata function)
-       ["R" random]
-       pipe)
-  lux/test)
-
-(def: gen-tree
-  (R;Random (tree;Tree Nat))
-  (R;rec (lambda [gen-tree]
-           (do R;Monad
-             ## Each branch can have, at most, 1 child.
-             [size (|> R;nat (:: @ map (n.% +2)))]
-             (R;seq R;nat
-                    (R;list size gen-tree))))))
-
-(def: (to-end zipper)
-  (All [a] (-> (&;Zipper a) (&;Zipper a)))
-  (loop [zipper zipper]
-    (if (&;end? zipper)
-      zipper
-      (recur (&;next zipper)))))
-
-(test: "Zippers"
-  [sample gen-tree
-   new-val R;nat
-   pre-val R;nat
-   post-val R;nat
-   #let [(^open "Tree/") (tree;Eq number;Eq)
-         (^open "List/") (list;Eq number;Eq)]]
-  ($_ seq
-      (assert "Trees can be converted to/from zippers."
-              (|> sample
-                  &;from-tree &;to-tree
-                  (Tree/= sample)))
-
-      (assert "Creating a zipper gives you a root node."
-              (|> sample &;from-tree &;root?))
-      
-      (assert "Can move down inside branches. Can move up from lower nodes."
-              (let [zipper (&;from-tree sample)]
-                (if (&;branch? zipper)
-                  (let [child (|> zipper &;down)]
-                    (and (not (Tree/= sample (&;to-tree child)))
-                         (|> child &;parent (default (undefined)) (is zipper))
-                         (|> child &;up (is zipper) not)
-                         (|> child &;root (is zipper) not)))
-                  (and (&;leaf? zipper)
-                       (|> zipper (&;prepend-child new-val) &;branch?)))))
-
-      (assert "Can prepend and append children."
-              (let [zipper (&;from-tree sample)]
-                (if (&;branch? zipper)
-                  (let [mid-val (|> zipper &;down &;value)
-                        zipper (|> zipper
-                                   (&;prepend-child pre-val)
-                                   (&;append-child post-val))]
-                    (and (|> zipper &;down &;value (is pre-val))
-                         (|> zipper &;down &;right &;value (is mid-val))
-                         (|> zipper &;down &;right &;right &;value (is post-val))
-                         (|> zipper &;down &;rightmost &;leftmost &;value (is pre-val))
-                         (|> zipper &;down &;right &;left &;value (is pre-val))
-                         (|> zipper &;down &;rightmost &;value (is post-val))))
-                  true)))
-
-      (assert "Can insert children around a node (unless it's root)."
-              (let [zipper (&;from-tree sample)]
-                (if (&;branch? zipper)
-                  (let [mid-val (|> zipper &;down &;value)
-                        zipper (|> zipper
-                                   &;down
-                                   (&;insert-left pre-val)
-                                   (default (undefined))
-                                   (&;insert-right post-val)
-                                   (default (undefined))
-                                   &;up)]
-                    (and (|> zipper &;down &;value (is pre-val))
-                         (|> zipper &;down &;right &;value (is mid-val))
-                         (|> zipper &;down &;right &;right &;value (is post-val))
-                         (|> zipper &;down &;rightmost &;leftmost &;value (is pre-val))
-                         (|> zipper &;down &;right &;left &;value (is pre-val))
-                         (|> zipper &;down &;rightmost &;value (is post-val))))
-                  (and (|> zipper (&;insert-left pre-val) (case> (#;Some _) false
-                                                                 #;None     true))
-                       (|> zipper (&;insert-right post-val) (case> (#;Some _) false
-                                                                   #;None     true))))))
-      
-      (assert "Can set and update the value of a node."
-              (|> sample &;from-tree (&;set new-val) &;value (n.= new-val)))
-
-      (assert "Zipper traversal follows the outline of the tree depth-first."
-              (List/= (tree;flatten sample)
-                      (loop [zipper (&;from-tree sample)]
-                        (if (&;end? zipper)
-                          (list (&;value zipper))
-                          (#;Cons (&;value zipper)
-                                  (recur (&;next zipper)))))))
-
-      (assert "Backwards zipper traversal yield reverse tree flatten."
-              (List/= (list;reverse (tree;flatten sample))
-                      (loop [zipper (to-end (&;from-tree sample))]
-                        (if (&;root? zipper)
-                          (list (&;value zipper))
-                          (#;Cons (&;value zipper)
-                                  (recur (&;prev zipper)))))))
-
-      (assert "Can remove nodes (except root nodes)."
-              (let [zipper (&;from-tree sample)]
-                (if (&;branch? zipper)
-                  (and (|> zipper &;down &;root? not)
-                       (|> zipper &;down &;remove (case> #;None false
-                                                         (#;Some node) (&;root? node))))
-                  (|> zipper &;remove (case> #;None     true
-                                             (#;Some _) false)))))
-      ))
diff --git a/stdlib/test/test/lux/lexer/regex.lux b/stdlib/test/test/lux/lexer/regex.lux
new file mode 100644
index 000000000..4a9f01c27
--- /dev/null
+++ b/stdlib/test/test/lux/lexer/regex.lux
@@ -0,0 +1,274 @@
+##  Copyright (c) Eduardo Julian. All rights reserved.
+##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
+##  If a copy of the MPL was not distributed with this file,
+##  You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(;module:
+  lux
+  (lux (codata [io])
+       (control monad)
+       (data [error #- fail]
+             [product]
+             [text "T/" Eq]
+             text/format)
+       [compiler]
+       (macro [ast]
+              ["s" syntax #+ syntax:])
+       ["R" random]
+       pipe
+       [lexer]
+       (lexer ["&" regex]))
+  lux/test)
+
+## [Utils]
+(def: (should-pass regex input)
+  (-> (lexer;Lexer Text) Text Bool)
+  (|> (lexer;run input regex)
+      (case> (#;Right parsed)
+             (T/= parsed input)
+
+             _
+             false)))
+
+(def: (should-passT test regex input)
+  (-> Text (lexer;Lexer Text) Text Bool)
+  (|> (lexer;run input regex)
+      (case> (#;Right parsed)
+             (T/= test parsed)
+
+             _
+             false)))
+
+(def: (should-fail regex input)
+  (All [a] (-> (lexer;Lexer a) Text Bool))
+  (|> (lexer;run input regex)
+      (case> (#;Left _) true _ false)))
+
+(syntax: (should-check pattern regex input)
+  (wrap (list (` (|> (lexer;run (~ input) (~ regex))
+                     (case> (^ (#;Right (~ pattern)))
+                            true
+
+                            (~' _)
+                            false))))))
+
+## [Tests]
+(test: "Regular Expressions [Basics]"
+  (assert "Can parse character literals."
+          (and (should-pass (&;regex "a") "a")
+               (should-fail (&;regex "a") ".")
+               (should-pass (&;regex "\\.") ".")
+               (should-fail (&;regex "\\.") "a"))))
+
+(test: "Regular Expressions [System character classes]"
+  ($_ seq
+      (assert "Can parse anything."
+              (should-pass (&;regex ".") "a"))
+
+      (assert "Can parse digits."
+              (and (should-pass (&;regex "\\d") "0")
+                   (should-fail (&;regex "\\d") "m")))
+
+      (assert "Can parse non digits."
+              (and (should-pass (&;regex "\\D") "m")
+                   (should-fail (&;regex "\\D") "0")))
+
+      (assert "Can parse white-space."
+              (and (should-pass (&;regex "\\s") " ")
+                   (should-fail (&;regex "\\s") "m")))
+
+      (assert "Can parse non white-space."
+              (and (should-pass (&;regex "\\S") "m")
+                   (should-fail (&;regex "\\S") " ")))
+
+      (assert "Can parse word characters."
+              (and (should-pass (&;regex "\\w") "_")
+                   (should-fail (&;regex "\\w") "^")))
+
+      (assert "Can parse non word characters."
+              (and (should-pass (&;regex "\\W") ".")
+                   (should-fail (&;regex "\\W") "a")))
+      ))
+
+(test: "Regular Expressions [Special system character classes : Part 1]"
+  ($_ seq
+      (assert "Can parse using special character classes."
+              (and (and (should-pass (&;regex "\\p{Lower}") "m")
+                        (should-fail (&;regex "\\p{Lower}") "M"))
+
+                   (and (should-pass (&;regex "\\p{Upper}") "M")
+                        (should-fail (&;regex "\\p{Upper}") "m"))
+
+                   (and (should-pass (&;regex "\\p{Alpha}") "M")
+                        (should-fail (&;regex "\\p{Alpha}") "0"))
+
+                   (and (should-pass (&;regex "\\p{Digit}") "1")
+                        (should-fail (&;regex "\\p{Digit}") "n"))
+
+                   (and (should-pass (&;regex "\\p{Alnum}") "1")
+                        (should-fail (&;regex "\\p{Alnum}") "."))
+
+                   (and (should-pass (&;regex "\\p{Space}") " ")
+                        (should-fail (&;regex "\\p{Space}") "."))
+                   ))
+      ))
+
+(test: "Regular Expressions [Special system character classes : Part 2]"
+  ($_ seq
+      (assert "Can parse using special character classes."
+              (and (and (should-pass (&;regex "\\p{HexDigit}") "a")
+                        (should-fail (&;regex "\\p{HexDigit}") "."))
+
+                   (and (should-pass (&;regex "\\p{OctDigit}") "6")
+                        (should-fail (&;regex "\\p{OctDigit}") "."))
+
+                   (and (should-pass (&;regex "\\p{Blank}") "\t")
+                        (should-fail (&;regex "\\p{Blank}") "."))
+
+                   (and (should-pass (&;regex "\\p{ASCII}") "\t")
+                        (should-fail (&;regex "\\p{ASCII}") "\u1234"))
+
+                   (and (should-pass (&;regex "\\p{Contrl}") "\u0012")
+                        (should-fail (&;regex "\\p{Contrl}") "a"))
+
+                   (and (should-pass (&;regex "\\p{Punct}") "@")
+                        (should-fail (&;regex "\\p{Punct}") "a"))
+
+                   (and (should-pass (&;regex "\\p{Graph}") "@")
+                        (should-fail (&;regex "\\p{Graph}") " "))
+
+                   (and (should-pass (&;regex "\\p{Print}") "\u0020")
+                        (should-fail (&;regex "\\p{Print}") "\u1234"))
+                   ))
+      ))
+
+(test: "Regular Expressions [Custom character classes : Part 1]"
+  ($_ seq
+      (assert "Can parse using custom character classes."
+              (and (should-pass (&;regex "[abc]") "a")
+                   (should-fail (&;regex "[abc]") "m")))
+
+      (assert "Can parse using character ranges."
+              (and (should-pass (&;regex "[a-z]") "a")
+                   (should-pass (&;regex "[a-z]") "m")
+                   (should-pass (&;regex "[a-z]") "z")))
+
+      (assert "Can combine character ranges."
+              (and (should-pass (&;regex "[a-zA-Z]") "a")
+                   (should-pass (&;regex "[a-zA-Z]") "m")
+                   (should-pass (&;regex "[a-zA-Z]") "z")
+                   (should-pass (&;regex "[a-zA-Z]") "A")
+                   (should-pass (&;regex "[a-zA-Z]") "M")
+                   (should-pass (&;regex "[a-zA-Z]") "Z")))
+      ))
+
+(test: "Regular Expressions [Custom character classes : Part 2]"
+  ($_ seq
+      (assert "Can negate custom character classes."
+              (and (should-fail (&;regex "[^abc]") "a")
+                   (should-pass (&;regex "[^abc]") "m")))
+
+      (assert "Can negate character ranges.."
+              (and (should-fail (&;regex "[^a-z]") "a")
+                   (should-pass (&;regex "[^a-z]") "0")))
+
+      (assert "Can parse negate combinations of character ranges."
+              (and (should-fail (&;regex "[^a-zA-Z]") "a")
+                   (should-pass (&;regex "[^a-zA-Z]") "0")))
+      ))
+
+(test: "Regular Expressions [Custom character classes : Part 3]"
+  ($_ seq
+      (assert "Can make custom character classes more specific."
+              (and (let [RE (&;regex "[a-z&&[def]]")]
+                     (and (should-fail RE "a")
+                          (should-pass RE "d")))
+
+                   (let [RE (&;regex "[a-z&&[^bc]]")]
+                     (and (should-pass RE "a")
+                          (should-fail RE "b")))
+
+                   (let [RE (&;regex "[a-z&&[^m-p]]")]
+                     (and (should-pass RE "a")
+                          (should-fail RE "m")
+                          (should-fail RE "p")))))
+      ))
+
+(test: "Regular Expressions [Reference]"
+  (let [number (&;regex "\\d+")]
+    (assert "Can build complex regexs by combining simpler ones."
+            (should-check ["809-345-6789" "809" "345" "6789"] (&;regex "(\\@)-(\\@)-(\\@)") "809-345-6789"))))
+
+(test: "Regular Expressions [Fuzzy Quantifiers]"
+  ($_ seq
+      (assert "Can sequentially combine patterns."
+              (should-passT "aa" (&;regex "aa") "aa"))
+
+      (assert "Can match patterns optionally."
+              (and (should-passT "a" (&;regex "a?") "a")
+                   (should-passT "" (&;regex "a?") "")))
+
+      (assert "Can match a pattern 0 or more times."
+              (and (should-passT "aaa" (&;regex "a*") "aaa")
+                   (should-passT "" (&;regex "a*") "")))
+
+      (assert "Can match a pattern 1 or more times."
+              (and (should-passT "aaa" (&;regex "a+") "aaa")
+                   (should-passT "a" (&;regex "a+") "a")
+                   (should-fail (&;regex "a+") "")))
+      ))
+
+(test: "Regular Expressions [Crisp Quantifiers]"
+  ($_ seq
+      (assert "Can match a pattern N times."
+              (and (should-passT "aa" (&;regex "a{2}") "aa")
+                   (should-passT "a" (&;regex "a{1}") "aa")
+                   (should-fail (&;regex "a{3}") "aa")))
+
+      (assert "Can match a pattern at-least N times."
+              (and (should-passT "aa" (&;regex "a{1,}") "aa")
+                   (should-passT "aa" (&;regex "a{2,}") "aa")
+                   (should-fail (&;regex "a{3,}") "aa")))
+
+      (assert "Can match a pattern at-most N times."
+              (and (should-passT "a" (&;regex "a{,1}") "aa")
+                   (should-passT "aa" (&;regex "a{,2}") "aa")
+                   (should-passT "aa" (&;regex "a{,3}") "aa")))
+
+      (assert "Can match a pattern between N and M times."
+              (and (should-passT "a" (&;regex "a{1,2}") "a")
+                   (should-passT "aa" (&;regex "a{1,2}") "aa")
+                   (should-passT "aa" (&;regex "a{1,2}") "aaa")))
+      ))
+
+(test: "Regular Expressions [Groups]"
+  ($_ seq
+      (assert "Can extract groups of sub-matches specified in a pattern."
+              (and (should-check ["abc" "b"] (&;regex "a(.)c") "abc")
+                   (should-check ["abbbbbc" "bbbbb"] (&;regex "a(b+)c") "abbbbbc")
+                   (should-check ["809-345-6789" "809" "345" "6789"] (&;regex "(\\d{3})-(\\d{3})-(\\d{4})") "809-345-6789")
+                   (should-check ["809-345-6789" "809" "6789"] (&;regex "(\\d{3})-(?:\\d{3})-(\\d{4})") "809-345-6789")
+                   (should-check ["809-809-6789" "809" "6789"] (&;regex "(\\d{3})-\\0-(\\d{4})") "809-809-6789")
+                   (should-check ["809-809-6789" "809" "6789"] (&;regex "(?\\d{3})-\\k-(\\d{4})") "809-809-6789")
+                   (should-check ["809-809-6789-6789" "809" "6789"] (&;regex "(?\\d{3})-\\k-(\\d{4})-\\0") "809-809-6789-6789")))
+
+      (assert "Can specify groups within groups."
+              (should-check ["809-345-6789" "809" ["345-6789" "345" "6789"]] (&;regex "(\\d{3})-((\\d{3})-(\\d{4}))") "809-345-6789"))
+      ))
+
+(test: "Regular Expressions [Alternation]"
+  ($_ seq
+      (assert "Can specify alternative patterns."
+              (and (should-check ["a" (+0 [])] (&;regex "a|b") "a")
+                   (should-check ["b" (+1 [])] (&;regex "a|b") "b")
+                   (should-fail (&;regex "a|b") "c")))
+
+      (assert "Can have groups within alternations."
+              (and (should-check ["abc" (+0 ["b" "c"])] (&;regex "a(.)(.)|b(.)(.)") "abc")
+                   (should-check ["bcd" (+1 ["c" "d"])] (&;regex "a(.)(.)|b(.)(.)") "bcd")
+                   (should-fail (&;regex "a(.)(.)|b(.)(.)") "cde")
+
+                   (should-check ["809-345-6789" (+0 ["809" "345-6789" "345" "6789"])]
+                                 (&;regex "(\\d{3})-((\\d{3})-(\\d{4}))|b(.)d")
+                                 "809-345-6789")))
+      ))
diff --git a/stdlib/test/test/lux/macro/syntax.lux b/stdlib/test/test/lux/macro/syntax.lux
index 1fabb09ad..2755bbf8e 100644
--- a/stdlib/test/test/lux/macro/syntax.lux
+++ b/stdlib/test/test/lux/macro/syntax.lux
@@ -79,7 +79,7 @@
                           ["Can parse Bool syntax."   true           ast;bool   bool;Eq   s;bool]
                           ["Can parse Nat syntax."    +123           ast;nat    number;Eq  s;nat]
                           ["Can parse Int syntax."    123            ast;int    number;Eq  s;int]
-                          ["Can parse Frac syntax."   .123           ast;frac   number;Eq s;frac]
+                          ["Can parse Deg syntax."   .123           ast;deg   number;Eq s;deg]
                           ["Can parse Real syntax."   123.0          ast;real   number;Eq s;real]
                           ["Can parse Char syntax."   #"\n"          ast;char   char;Eq   s;char]
                           ["Can parse Text syntax."   "\n"           ast;text   text;Eq   s;text]
diff --git a/stdlib/test/test/lux/math/simple.lux b/stdlib/test/test/lux/math/simple.lux
index bfa313708..235723f25 100644
--- a/stdlib/test/test/lux/math/simple.lux
+++ b/stdlib/test/test/lux/math/simple.lux
@@ -40,7 +40,7 @@
   ["Nat"  R;nat  n.= n.+ n.- n.* n./ n.% +0]
   ["Int"  R;int  i.= i.+ i.- i.* i./ i.%  0]
   ["Real" R;real r.= r.+ r.- r.* r./ r.%  0.0]
-  ## ["Frac" R;frac f.= f.+ f.- f.* f./ f.% .0]
+  ["Deg" R;deg d.= d.+ d.- d.* d./ d.% .0]
   )
 
 (do-template [     ]
@@ -61,7 +61,7 @@
   ["Nat"  R;nat  n.< n.<= n.> n.>=]
   ["Int"  R;int  i.< i.<= i.> i.>=]
   ["Real" R;real r.< r.<= r.> r.>=]
-  ## ["Frac" R;frac f.< f.<= f.> f.>=]
+  ["Deg" R;deg d.< d.<= d.> d.>=]
   )
 
 (do-template [  <=>  ]
diff --git a/stdlib/test/test/lux/regex.lux b/stdlib/test/test/lux/regex.lux
deleted file mode 100644
index 6c6854ce0..000000000
--- a/stdlib/test/test/lux/regex.lux
+++ /dev/null
@@ -1,274 +0,0 @@
-##  Copyright (c) Eduardo Julian. All rights reserved.
-##  This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
-##  If a copy of the MPL was not distributed with this file,
-##  You can obtain one at http://mozilla.org/MPL/2.0/.
-
-(;module:
-  lux
-  (lux (codata [io])
-       (control monad)
-       (data [error #- fail]
-             [product]
-             [text "T/" Eq]
-             text/format)
-       [compiler]
-       (macro [ast]
-              ["s" syntax #+ syntax:])
-       ["R" random]
-       pipe
-       [lexer]
-       ["&" regex])
-  lux/test)
-
-## [Utils]
-(def: (should-pass regex input)
-  (-> (lexer;Lexer Text) Text Bool)
-  (|> (lexer;run input regex)
-      (case> (#;Right parsed)
-             (T/= parsed input)
-
-             _
-             false)))
-
-(def: (should-passT test regex input)
-  (-> Text (lexer;Lexer Text) Text Bool)
-  (|> (lexer;run input regex)
-      (case> (#;Right parsed)
-             (T/= test parsed)
-
-             _
-             false)))
-
-(def: (should-fail regex input)
-  (All [a] (-> (lexer;Lexer a) Text Bool))
-  (|> (lexer;run input regex)
-      (case> (#;Left _) true _ false)))
-
-(syntax: (should-check pattern regex input)
-  (wrap (list (` (|> (lexer;run (~ input) (~ regex))
-                     (case> (^ (#;Right (~ pattern)))
-                            true
-
-                            (~' _)
-                            false))))))
-
-## [Tests]
-(test: "Regular Expressions [Basics]"
-  (assert "Can parse character literals."
-          (and (should-pass (&;regex "a") "a")
-               (should-fail (&;regex "a") ".")
-               (should-pass (&;regex "\\.") ".")
-               (should-fail (&;regex "\\.") "a"))))
-
-(test: "Regular Expressions [System character classes]"
-  ($_ seq
-      (assert "Can parse anything."
-              (should-pass (&;regex ".") "a"))
-
-      (assert "Can parse digits."
-              (and (should-pass (&;regex "\\d") "0")
-                   (should-fail (&;regex "\\d") "m")))
-
-      (assert "Can parse non digits."
-              (and (should-pass (&;regex "\\D") "m")
-                   (should-fail (&;regex "\\D") "0")))
-
-      (assert "Can parse white-space."
-              (and (should-pass (&;regex "\\s") " ")
-                   (should-fail (&;regex "\\s") "m")))
-
-      (assert "Can parse non white-space."
-              (and (should-pass (&;regex "\\S") "m")
-                   (should-fail (&;regex "\\S") " ")))
-
-      (assert "Can parse word characters."
-              (and (should-pass (&;regex "\\w") "_")
-                   (should-fail (&;regex "\\w") "^")))
-
-      (assert "Can parse non word characters."
-              (and (should-pass (&;regex "\\W") ".")
-                   (should-fail (&;regex "\\W") "a")))
-      ))
-
-(test: "Regular Expressions [Special system character classes : Part 1]"
-  ($_ seq
-      (assert "Can parse using special character classes."
-              (and (and (should-pass (&;regex "\\p{Lower}") "m")
-                        (should-fail (&;regex "\\p{Lower}") "M"))
-
-                   (and (should-pass (&;regex "\\p{Upper}") "M")
-                        (should-fail (&;regex "\\p{Upper}") "m"))
-
-                   (and (should-pass (&;regex "\\p{Alpha}") "M")
-                        (should-fail (&;regex "\\p{Alpha}") "0"))
-
-                   (and (should-pass (&;regex "\\p{Digit}") "1")
-                        (should-fail (&;regex "\\p{Digit}") "n"))
-
-                   (and (should-pass (&;regex "\\p{Alnum}") "1")
-                        (should-fail (&;regex "\\p{Alnum}") "."))
-
-                   (and (should-pass (&;regex "\\p{Space}") " ")
-                        (should-fail (&;regex "\\p{Space}") "."))
-                   ))
-      ))
-
-(test: "Regular Expressions [Special system character classes : Part 2]"
-  ($_ seq
-      (assert "Can parse using special character classes."
-              (and (and (should-pass (&;regex "\\p{HexDigit}") "a")
-                        (should-fail (&;regex "\\p{HexDigit}") "."))
-
-                   (and (should-pass (&;regex "\\p{OctDigit}") "6")
-                        (should-fail (&;regex "\\p{OctDigit}") "."))
-
-                   (and (should-pass (&;regex "\\p{Blank}") "\t")
-                        (should-fail (&;regex "\\p{Blank}") "."))
-
-                   (and (should-pass (&;regex "\\p{ASCII}") "\t")
-                        (should-fail (&;regex "\\p{ASCII}") "\u1234"))
-
-                   (and (should-pass (&;regex "\\p{Contrl}") "\u0012")
-                        (should-fail (&;regex "\\p{Contrl}") "a"))
-
-                   (and (should-pass (&;regex "\\p{Punct}") "@")
-                        (should-fail (&;regex "\\p{Punct}") "a"))
-
-                   (and (should-pass (&;regex "\\p{Graph}") "@")
-                        (should-fail (&;regex "\\p{Graph}") " "))
-
-                   (and (should-pass (&;regex "\\p{Print}") "\u0020")
-                        (should-fail (&;regex "\\p{Print}") "\u1234"))
-                   ))
-      ))
-
-(test: "Regular Expressions [Custom character classes : Part 1]"
-  ($_ seq
-      (assert "Can parse using custom character classes."
-              (and (should-pass (&;regex "[abc]") "a")
-                   (should-fail (&;regex "[abc]") "m")))
-
-      (assert "Can parse using character ranges."
-              (and (should-pass (&;regex "[a-z]") "a")
-                   (should-pass (&;regex "[a-z]") "m")
-                   (should-pass (&;regex "[a-z]") "z")))
-
-      (assert "Can combine character ranges."
-              (and (should-pass (&;regex "[a-zA-Z]") "a")
-                   (should-pass (&;regex "[a-zA-Z]") "m")
-                   (should-pass (&;regex "[a-zA-Z]") "z")
-                   (should-pass (&;regex "[a-zA-Z]") "A")
-                   (should-pass (&;regex "[a-zA-Z]") "M")
-                   (should-pass (&;regex "[a-zA-Z]") "Z")))
-      ))
-
-(test: "Regular Expressions [Custom character classes : Part 2]"
-  ($_ seq
-      (assert "Can negate custom character classes."
-              (and (should-fail (&;regex "[^abc]") "a")
-                   (should-pass (&;regex "[^abc]") "m")))
-
-      (assert "Can negate character ranges.."
-              (and (should-fail (&;regex "[^a-z]") "a")
-                   (should-pass (&;regex "[^a-z]") "0")))
-
-      (assert "Can parse negate combinations of character ranges."
-              (and (should-fail (&;regex "[^a-zA-Z]") "a")
-                   (should-pass (&;regex "[^a-zA-Z]") "0")))
-      ))
-
-(test: "Regular Expressions [Custom character classes : Part 3]"
-  ($_ seq
-      (assert "Can make custom character classes more specific."
-              (and (let [RE (&;regex "[a-z&&[def]]")]
-                     (and (should-fail RE "a")
-                          (should-pass RE "d")))
-
-                   (let [RE (&;regex "[a-z&&[^bc]]")]
-                     (and (should-pass RE "a")
-                          (should-fail RE "b")))
-
-                   (let [RE (&;regex "[a-z&&[^m-p]]")]
-                     (and (should-pass RE "a")
-                          (should-fail RE "m")
-                          (should-fail RE "p")))))
-      ))
-
-(test: "Regular Expressions [Reference]"
-  (let [number (&;regex "\\d+")]
-    (assert "Can build complex regexs by combining simpler ones."
-            (should-check ["809-345-6789" "809" "345" "6789"] (&;regex "(\\@)-(\\@)-(\\@)") "809-345-6789"))))
-
-(test: "Regular Expressions [Fuzzy Quantifiers]"
-  ($_ seq
-      (assert "Can sequentially combine patterns."
-              (should-passT "aa" (&;regex "aa") "aa"))
-
-      (assert "Can match patterns optionally."
-              (and (should-passT "a" (&;regex "a?") "a")
-                   (should-passT "" (&;regex "a?") "")))
-
-      (assert "Can match a pattern 0 or more times."
-              (and (should-passT "aaa" (&;regex "a*") "aaa")
-                   (should-passT "" (&;regex "a*") "")))
-
-      (assert "Can match a pattern 1 or more times."
-              (and (should-passT "aaa" (&;regex "a+") "aaa")
-                   (should-passT "a" (&;regex "a+") "a")
-                   (should-fail (&;regex "a+") "")))
-      ))
-
-(test: "Regular Expressions [Crisp Quantifiers]"
-  ($_ seq
-      (assert "Can match a pattern N times."
-              (and (should-passT "aa" (&;regex "a{2}") "aa")
-                   (should-passT "a" (&;regex "a{1}") "aa")
-                   (should-fail (&;regex "a{3}") "aa")))
-
-      (assert "Can match a pattern at-least N times."
-              (and (should-passT "aa" (&;regex "a{1,}") "aa")
-                   (should-passT "aa" (&;regex "a{2,}") "aa")
-                   (should-fail (&;regex "a{3,}") "aa")))
-
-      (assert "Can match a pattern at-most N times."
-              (and (should-passT "a" (&;regex "a{,1}") "aa")
-                   (should-passT "aa" (&;regex "a{,2}") "aa")
-                   (should-passT "aa" (&;regex "a{,3}") "aa")))
-
-      (assert "Can match a pattern between N and M times."
-              (and (should-passT "a" (&;regex "a{1,2}") "a")
-                   (should-passT "aa" (&;regex "a{1,2}") "aa")
-                   (should-passT "aa" (&;regex "a{1,2}") "aaa")))
-      ))
-
-(test: "Regular Expressions [Groups]"
-  ($_ seq
-      (assert "Can extract groups of sub-matches specified in a pattern."
-              (and (should-check ["abc" "b"] (&;regex "a(.)c") "abc")
-                   (should-check ["abbbbbc" "bbbbb"] (&;regex "a(b+)c") "abbbbbc")
-                   (should-check ["809-345-6789" "809" "345" "6789"] (&;regex "(\\d{3})-(\\d{3})-(\\d{4})") "809-345-6789")
-                   (should-check ["809-345-6789" "809" "6789"] (&;regex "(\\d{3})-(?:\\d{3})-(\\d{4})") "809-345-6789")
-                   (should-check ["809-809-6789" "809" "6789"] (&;regex "(\\d{3})-\\0-(\\d{4})") "809-809-6789")
-                   (should-check ["809-809-6789" "809" "6789"] (&;regex "(?\\d{3})-\\k-(\\d{4})") "809-809-6789")
-                   (should-check ["809-809-6789-6789" "809" "6789"] (&;regex "(?\\d{3})-\\k-(\\d{4})-\\0") "809-809-6789-6789")))
-
-      (assert "Can specify groups within groups."
-              (should-check ["809-345-6789" "809" ["345-6789" "345" "6789"]] (&;regex "(\\d{3})-((\\d{3})-(\\d{4}))") "809-345-6789"))
-      ))
-
-(test: "Regular Expressions [Alternation]"
-  ($_ seq
-      (assert "Can specify alternative patterns."
-              (and (should-check ["a" (+0 [])] (&;regex "a|b") "a")
-                   (should-check ["b" (+1 [])] (&;regex "a|b") "b")
-                   (should-fail (&;regex "a|b") "c")))
-
-      (assert "Can have groups within alternations."
-              (and (should-check ["abc" (+0 ["b" "c"])] (&;regex "a(.)(.)|b(.)(.)") "abc")
-                   (should-check ["bcd" (+1 ["c" "d"])] (&;regex "a(.)(.)|b(.)(.)") "bcd")
-                   (should-fail (&;regex "a(.)(.)|b(.)(.)") "cde")
-
-                   (should-check ["809-345-6789" (+0 ["809" "345-6789" "345" "6789"])]
-                                 (&;regex "(\\d{3})-((\\d{3})-(\\d{4}))|b(.)d")
-                                 "809-345-6789")))
-      ))
diff --git a/stdlib/test/tests.lux b/stdlib/test/tests.lux
index c57ca61c5..8e0c165c1 100644
--- a/stdlib/test/tests.lux
+++ b/stdlib/test/tests.lux
@@ -15,7 +15,7 @@
              ["_;" host]
              ["_;" pipe]
              ["_;" lexer]
-             ["_;" regex]
+             (lexer ["_;" regex])
              (codata ["_;" io]
                      ["_;" env]
                      ["_;" state]
@@ -47,9 +47,9 @@
                            [queue]
                            [set]
                            [stack]
-                           [tree]
                            ## [vector]
-                           [zipper])
+                           (tree [rose]
+                                 [zipper]))
                    (text [format])
                    )
              ["_;" math]
-- 
cgit v1.2.3