aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2017-02-16 20:09:52 -0400
committerEduardo Julian2017-02-16 20:09:52 -0400
commitb0114f4871a6a2654fa2edc667a635a97ae76b19 (patch)
tree9e501a76cfb77a1b523384660e0020a2a15ffe44
parent47ddcadd07234f32d6d4f1411548ccf9665e60c3 (diff)
- Implemented several new procedures.
- Improved Lux-to-JS interactions. - Parallel compilation works for the JS backend. - Added more primitive functionality to the JS runtime. - More common procedures.
Diffstat (limited to '')
-rw-r--r--luxc/src/lux/analyser/proc/common.clj125
-rw-r--r--luxc/src/lux/compiler/js.clj3
-rw-r--r--luxc/src/lux/compiler/js/base.clj54
-rw-r--r--luxc/src/lux/compiler/js/lux.clj22
-rw-r--r--luxc/src/lux/compiler/js/proc/common.clj192
-rw-r--r--luxc/src/lux/compiler/js/rt.clj108
-rw-r--r--luxc/src/lux/compiler/jvm/proc/common.clj144
-rw-r--r--luxc/src/lux/compiler/jvm/rt.clj30
-rw-r--r--stdlib/source/lux.lux162
-rw-r--r--stdlib/source/lux/data/number.lux105
-rw-r--r--stdlib/source/lux/data/text.lux8
-rw-r--r--stdlib/source/lux/math/complex.lux8
-rw-r--r--stdlib/test/test/lux.lux16
-rw-r--r--stdlib/test/test/lux/data/text.lux8
-rw-r--r--stdlib/test/test/lux/math/complex.lux16
15 files changed, 707 insertions, 294 deletions
diff --git a/luxc/src/lux/analyser/proc/common.clj b/luxc/src/lux/analyser/proc/common.clj
index 3bbc47e88..4a4048c1c 100644
--- a/luxc/src/lux/analyser/proc/common.clj
+++ b/luxc/src/lux/analyser/proc/common.clj
@@ -6,7 +6,7 @@
[type :as &type])
(lux.analyser [base :as &&])))
-(defn ^:private analyse-lux-== [analyse exo-type ?values]
+(defn ^:private analyse-lux-is [analyse exo-type ?values]
(&type/with-var
(fn [$var]
(|do [:let [(&/$Cons left (&/$Cons right (&/$Nil))) ?values]
@@ -15,7 +15,7 @@
_ (&type/check exo-type &type/Bool)
_cursor &/cursor]
(return (&/|list (&&/|meta exo-type _cursor
- (&&/$proc (&/T ["lux" "=="]) (&/|list =left =right) (&/|list)))))))))
+ (&&/$proc (&/T ["lux" "is"]) (&/|list =left =right) (&/|list)))))))))
(do-template [<name> <proc> <input-type> <output-type>]
(defn <name> [analyse exo-type ?values]
@@ -31,6 +31,66 @@
^:private analyse-text-append ["text" "append"] &type/Text &type/Text
)
+(do-template [<name> <proc-name>]
+ (defn <name> [analyse exo-type ?values]
+ (|do [:let [(&/$Cons text (&/$Cons part (&/$Nil))) ?values]
+ =text (&&/analyse-1 analyse &type/Text text)
+ =part (&&/analyse-1 analyse &type/Text part)
+ _ (&type/check exo-type (&/$AppT &type/Maybe &type/Nat))
+ _cursor &/cursor]
+ (return (&/|list (&&/|meta &type/Text _cursor
+ (&&/$proc (&/T ["text" <proc-name>])
+ (&/|list =text =part)
+ (&/|list)))))))
+
+ ^:private analyse-text-index "index"
+ ^:private analyse-text-last-index "last-index"
+ )
+
+(defn ^:private analyse-text-clip [analyse exo-type ?values]
+ (|do [:let [(&/$Cons text (&/$Cons from (&/$Cons to (&/$Nil)))) ?values]
+ =text (&&/analyse-1 analyse &type/Text text)
+ =from (&&/analyse-1 analyse &type/Nat from)
+ =to (&&/analyse-1 analyse &type/Nat to)
+ _ (&type/check exo-type (&/$AppT &type/Maybe &type/Text))
+ _cursor &/cursor]
+ (return (&/|list (&&/|meta exo-type _cursor
+ (&&/$proc (&/T ["text" "clip"])
+ (&/|list =text =from =to)
+ (&/|list)))))))
+
+(defn ^:private analyse-text-replace-all [analyse exo-type ?values]
+ (|do [:let [(&/$Cons text (&/$Cons to-find (&/$Cons replace-with (&/$Nil)))) ?values]
+ =text (&&/analyse-1 analyse &type/Text text)
+ =to-find (&&/analyse-1 analyse &type/Text to-find)
+ =replace-with (&&/analyse-1 analyse &type/Text replace-with)
+ _ (&type/check exo-type &type/Text)
+ _cursor &/cursor]
+ (return (&/|list (&&/|meta exo-type _cursor
+ (&&/$proc (&/T ["text" "replace-all"])
+ (&/|list =text =to-find =replace-with)
+ (&/|list)))))))
+
+(defn ^:private analyse-text-trim [analyse exo-type ?values]
+ (|do [:let [(&/$Cons text (&/$Nil)) ?values]
+ =text (&&/analyse-1 analyse &type/Text text)
+ _ (&type/check exo-type &type/Text)
+ _cursor &/cursor]
+ (return (&/|list (&&/|meta exo-type _cursor
+ (&&/$proc (&/T ["text" "trim"])
+ (&/|list =text)
+ (&/|list)))))))
+
+(defn ^:private analyse-text-size [analyse exo-type ?values]
+ (|do [:let [(&/$Cons text (&/$Nil)) ?values]
+ =text (&&/analyse-1 analyse &type/Text text)
+ _ (&type/check exo-type &type/Nat)
+ _cursor &/cursor]
+ (return (&/|list (&&/|meta &type/Text _cursor
+ (&&/$proc (&/T ["text" "size"])
+ (&/|list =text)
+ (&/|list)))))))
+
(do-template [<name> <op>]
(defn <name> [analyse exo-type ?values]
(|do [:let [(&/$Cons input (&/$Cons mask (&/$Nil))) ?values]
@@ -153,17 +213,20 @@
(return (&/|list (&&/|meta <type> _cursor
(&&/$proc (&/T <op>) (&/|list) (&/|list)))))))
- ^:private analyse-nat-min-value &type/Nat ["nat" "min-value"]
- ^:private analyse-nat-max-value &type/Nat ["nat" "max-value"]
+ ^:private analyse-nat-min-value &type/Nat ["nat" "min-value"]
+ ^:private analyse-nat-max-value &type/Nat ["nat" "max-value"]
- ^:private analyse-int-min-value &type/Int ["int" "min-value"]
- ^:private analyse-int-max-value &type/Int ["int" "max-value"]
+ ^:private analyse-int-min-value &type/Int ["int" "min-value"]
+ ^:private analyse-int-max-value &type/Int ["int" "max-value"]
- ^:private analyse-deg-min-value &type/Deg ["deg" "min-value"]
- ^:private analyse-deg-max-value &type/Deg ["deg" "max-value"]
+ ^:private analyse-deg-min-value &type/Deg ["deg" "min-value"]
+ ^:private analyse-deg-max-value &type/Deg ["deg" "max-value"]
- ^:private analyse-real-min-value &type/Real ["real" "min-value"]
- ^:private analyse-real-max-value &type/Real ["real" "max-value"]
+ ^:private analyse-real-min-value &type/Real ["real" "min-value"]
+ ^:private analyse-real-max-value &type/Real ["real" "max-value"]
+ ^:private analyse-real-not-a-number &type/Real ["real" "not-a-number"]
+ ^:private analyse-real-positive-infinity &type/Real ["real" "positive-infinity"]
+ ^:private analyse-real-negative-infinity &type/Real ["real" "negative-infinity"]
)
(do-template [<name> <from-type> <to-type> <op>]
@@ -175,16 +238,23 @@
(return (&/|list (&&/|meta <to-type> _cursor
(&&/$proc (&/T <op>) (&/|list =x) (&/|list)))))))
- ^:private analyse-nat-to-int &type/Nat &type/Int ["nat" "to-int"]
- ^:private analyse-nat-to-char &type/Nat &type/Char ["nat" "to-char"]
- ^: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-char-to-text &type/Char &type/Text ["char" "to-text"]
+ ^:private analyse-nat-to-int &type/Nat &type/Int ["nat" "to-int"]
+ ^:private analyse-int-to-nat &type/Int &type/Nat ["int" "to-nat"]
+
+ ^:private analyse-nat-to-char &type/Nat &type/Char ["nat" "to-char"]
+ ^:private analyse-char-to-nat &type/Char &type/Nat ["char" "to-nat"]
+
+ ^:private analyse-int-to-real &type/Int &type/Real ["int" "to-real"]
+ ^:private analyse-real-to-int &type/Real &type/Int ["real" "to-int"]
+ ^:private analyse-real-hash &type/Real &type/Nat ["real" "hash"]
+
+ ^:private analyse-char-to-text &type/Char &type/Text ["char" "to-text"]
- ^:private analyse-deg-to-real &type/Deg &type/Real ["deg" "to-real"]
- ^:private analyse-real-to-deg &type/Real &type/Deg ["real" "to-deg"]
+ ^:private analyse-deg-to-real &type/Deg &type/Real ["deg" "to-real"]
+ ^:private analyse-real-to-deg &type/Real &type/Deg ["real" "to-deg"]
- ^:private analyse-lux-log! &type/Text &/$UnitT ["io" "log!"]
+ ^:private analyse-lux-log &type/Text &/$UnitT ["io" "log"]
+ ^:private analyse-lux-error &type/Text &type/Bottom ["io" "error"]
)
(defn ^:private analyse-array-new [analyse exo-type ?values]
@@ -245,16 +315,23 @@
(case category
"lux"
(case proc
- "==" (analyse-lux-== analyse exo-type ?values))
+ "is" (analyse-lux-is analyse exo-type ?values))
"io"
(case proc
- "log!" (analyse-lux-log! analyse exo-type ?values))
+ "log" (analyse-lux-log analyse exo-type ?values)
+ "error" (analyse-lux-error analyse exo-type ?values))
"text"
(case proc
"=" (analyse-text-eq analyse exo-type ?values)
- "append" (analyse-text-append analyse exo-type ?values))
+ "append" (analyse-text-append analyse exo-type ?values)
+ "clip" (analyse-text-clip analyse exo-type ?values)
+ "index" (analyse-text-index analyse exo-type ?values)
+ "last-index" (analyse-text-last-index analyse exo-type ?values)
+ "size" (analyse-text-size analyse exo-type ?values)
+ "replace-all" (analyse-text-replace-all analyse exo-type ?values)
+ "trim" (analyse-text-trim analyse exo-type ?values))
"bit"
(case proc
@@ -305,6 +382,7 @@
"min-value" (analyse-int-min-value analyse exo-type ?values)
"max-value" (analyse-int-max-value analyse exo-type ?values)
"to-nat" (analyse-int-to-nat analyse exo-type ?values)
+ "to-real" (analyse-int-to-real analyse exo-type ?values)
)
"deg"
@@ -337,7 +415,12 @@
"decode" (analyse-real-decode analyse exo-type ?values)
"min-value" (analyse-real-min-value analyse exo-type ?values)
"max-value" (analyse-real-max-value analyse exo-type ?values)
+ "not-a-number" (analyse-real-not-a-number analyse exo-type ?values)
+ "positive-infinity" (analyse-real-positive-infinity analyse exo-type ?values)
+ "negative-infinity" (analyse-real-negative-infinity analyse exo-type ?values)
"to-deg" (analyse-real-to-deg analyse exo-type ?values)
+ "to-int" (analyse-real-to-int analyse exo-type ?values)
+ "hash" (analyse-real-hash analyse exo-type ?values)
)
"char"
diff --git a/luxc/src/lux/compiler/js.clj b/luxc/src/lux/compiler/js.clj
index a60afbc23..2e7d01d44 100644
--- a/luxc/src/lux/compiler/js.clj
+++ b/luxc/src/lux/compiler/js.clj
@@ -130,8 +130,7 @@
(let [file-name (str name ".lux")]
(|do [file-content (&&io/read-file source-dirs file-name)
:let [file-hash (hash file-content)
- ;; compile-module!! (&&parallel/parallel-compilation (partial compile-module source-dirs))
- compile-module!! (partial compile-module source-dirs)]]
+ compile-module!! (&&parallel/parallel-compilation (partial compile-module source-dirs))]]
;; (&/|eitherL (&&cache/load name))
(let [compiler-step (&analyser/analyse &optimizer/optimize eval! compile-module!! all-compilers)]
(|do [module-exists? (&a-module/exists? name)]
diff --git a/luxc/src/lux/compiler/js/base.clj b/luxc/src/lux/compiler/js/base.clj
index 62d440d6d..044a4f099 100644
--- a/luxc/src/lux/compiler/js/base.clj
+++ b/luxc/src/lux/compiler/js/base.clj
@@ -54,15 +54,31 @@
(&/adt->text obj)
)))
+(defn ^:private _toString_simple [^String obj]
+ (reify JSObject
+ (isFunction [self] true)
+ (call [self this args]
+ obj
+ )))
+
(def ^:private i64-mask (dec (bit-shift-left 1 32)))
-(defn ^:private to-i64 [value]
+(deftype I64 [value]
+ JSObject
+ (getMember [self member]
+ (condp = member
+ "H" (-> value (unsigned-bit-shift-right 32) (bit-and i64-mask) int)
+ "L" (-> value (bit-and i64-mask) int)
+ ;; else
+ (assert false (str "I64#getMember = " member)))))
+
+(defn ^:private encode-char [value]
(reify JSObject
(getMember [self member]
(condp = member
- "H" (-> value (unsigned-bit-shift-right 32) (bit-and i64-mask) int)
- "L" (-> value (bit-and i64-mask) int)
+ "C" value
+ ;; "toString" (_toString_simple value)
;; else
- (assert false (str "to-i64#getMember = " member))))))
+ (assert false (str "encode-char#getMember = " member))))))
(deftype LuxJsObject [obj]
JSObject
@@ -73,7 +89,10 @@
(new LuxJsObject value)
(instance? java.lang.Long value)
- (to-i64 value)
+ (new I64 value)
+
+ (instance? java.lang.Character value)
+ (encode-char (str value))
:else
value)))
@@ -81,15 +100,7 @@
(condp = member
"toString" (_toString_ obj)
"length" (alength obj)
- "slice" (let [wrap-lux-obj #(cond (instance? lux-obj-class %)
- (new LuxJsObject %)
-
- (instance? java.lang.Long %)
- (to-i64 %)
-
- :else
- %)]
- (_slice_ wrap-lux-obj obj))
+ "slice" (_slice_ #(new LuxJsObject %) obj)
;; else
(assert false (str "wrap-lux-obj#getMember = " member)))))
@@ -102,6 +113,13 @@
(and (.hasMember js-object "H")
(.hasMember js-object "L")))
+(defn ^:private encoded-char? [^ScriptObjectMirror js-object]
+ (.hasMember js-object "C"))
+
+(defn ^:private decode-char [^ScriptObjectMirror js-object]
+ (-> (.getMember js-object "C")
+ (.charAt 0)))
+
(defn ^:private parse-int64 [^ScriptObjectMirror js-object]
(+ (-> (.getMember js-object "H")
long
@@ -122,6 +140,9 @@
(instance? LuxJsObject js-object)
(.-obj ^LuxJsObject js-object)
+ (instance? I64 js-object)
+ (.-value ^I64 js-object)
+
;; (instance? Undefined js-object)
;; (assert false "UNDEFINED")
@@ -149,6 +170,9 @@
(int64? js-object)
(parse-int64 js-object)
+ (encoded-char? js-object)
+ (decode-char js-object)
+
:else
(assert false (str "Unknown kind of JS object: " js-object))))
@@ -169,5 +193,5 @@
(let [^String module* (&host/->module-class module)
module-dir (str @&&/!output-dir java.io.File/separator (.replace module* "/" java.io.File/separator))]
(do (.mkdirs (File. module-dir))
- (&&/write-file (str module-dir java.io.File/separator name ".js") (.getBytes script)))))]]
+ (&&/write-file (str module-dir java.io.File/separator (&host/def-name name) ".js") (.getBytes script)))))]]
(return nil)))
diff --git a/luxc/src/lux/compiler/js/lux.clj b/luxc/src/lux/compiler/js/lux.clj
index 61f21bf55..f0ad777c6 100644
--- a/luxc/src/lux/compiler/js/lux.clj
+++ b/luxc/src/lux/compiler/js/lux.clj
@@ -19,8 +19,11 @@
))
;; [Utils]
+(defn ^:private js-module [module]
+ (string/replace module "/" "$"))
+
(defn ^:private js-var-name [module name]
- (str (string/replace module "/" "$") "$" (&host/def-name name)))
+ (str (js-module module) "$" (&host/def-name name)))
(defn ^:private captured-name [register]
(str "$" register))
@@ -49,7 +52,7 @@
(return (str value)))
(defn compile-char [value]
- (return (str "\"" value "\"")))
+ (return (str "{C:\"" value "\"}")))
(defn compile-text [?value]
(return (pr-str ?value)))
@@ -279,7 +282,7 @@
(defn compile-function [compile arity ?scope ?env ?body]
(|do [:let [??scope (&/|reverse ?scope)
- function-name (str (&host/->module-class (&/|head ??scope))
+ function-name (str (js-module (&/|head ??scope))
"$" (&host/location (&/|tail ??scope)))
func-args (->> (&/|range* 0 (dec arity))
(&/|map (fn [register] (str "var " (register-name (inc register)) " = arguments[" register "];")))
@@ -323,12 +326,11 @@
(defn compile-def [compile ?name ?body def-meta]
(|do [module-name &/get-module-name
- class-loader &/loader
- :let [var-name (js-var-name module-name ?name)]]
+ class-loader &/loader]
(|case (&a-meta/meta-get &a-meta/alias-tag def-meta)
(&/$Some (&/$IdentA [r-module r-name]))
(if (= 1 (&/|length def-meta))
- (|do [def-value (&&/run-js! var-name)
+ (|do [def-value (&&/run-js! (js-var-name r-module r-name))
def-type (&a-module/def-type r-module r-name)
_ (&/without-repl-closure
(&a-module/define module-name ?name def-type def-meta def-value))]
@@ -339,7 +341,8 @@
(&/fail-with-loc "[Compilation Error] Invalid syntax for lux;alias meta-data. Must be an Ident.")
_
- (|do [=body (compile ?body)
+ (|do [:let [var-name (js-var-name module-name ?name)]
+ =body (compile ?body)
:let [def-js (str "var " var-name " = " =body ";")
is-type? (|case (&a-meta/meta-get &a-meta/type?-tag def-meta)
(&/$Some (&/$BoolA true))
@@ -348,8 +351,9 @@
_
false)
def-type (&a/expr-type* ?body)
- _ (&/|log! (string/replace def-js "
- _ (&&/run-js! def-js)
+ ;; _ (&/|log! (string/replace def-js "
+ ]
+ _ (&&/save-js! ?name def-js)
def-value (&&/run-js!+ var-name)
_ (&/without-repl-closure
(&a-module/define module-name ?name def-type def-meta def-value))
diff --git a/luxc/src/lux/compiler/js/proc/common.clj b/luxc/src/lux/compiler/js/proc/common.clj
index 385761dbe..23454914e 100644
--- a/luxc/src/lux/compiler/js/proc/common.clj
+++ b/luxc/src/lux/compiler/js/proc/common.clj
@@ -10,7 +10,8 @@
[optimizer :as &o])
[lux.analyser.base :as &a]
(lux.compiler.js [base :as &&]
- [rt :as &&rt])))
+ [rt :as &&rt]
+ [lux :as &&lux])))
;; [Resources]
;; (do-template [<name> <op>]
@@ -62,22 +63,11 @@
;; ^:private compile-bit-unsigned-shift-right Opcodes/LUSHR
;; )
-;; (defn ^:private compile-lux-== [compile ?values special-args]
-;; (|do [:let [(&/$Cons ?left (&/$Cons ?right (&/$Nil))) ?values]
-;; ^MethodVisitor *writer* &/get-writer
-;; _ (compile ?left)
-;; _ (compile ?right)
-;; :let [$then (new Label)
-;; $end (new Label)
-;; _ (doto *writer*
-;; (.visitJumpInsn Opcodes/IF_ACMPEQ $then)
-;; ;; else
-;; (.visitFieldInsn Opcodes/GETSTATIC "java/lang/Boolean" "FALSE" "Ljava/lang/Boolean;")
-;; (.visitJumpInsn Opcodes/GOTO $end)
-;; (.visitLabel $then)
-;; (.visitFieldInsn Opcodes/GETSTATIC "java/lang/Boolean" "TRUE" "Ljava/lang/Boolean;")
-;; (.visitLabel $end))]]
-;; (return nil)))
+(defn ^:private compile-lux-is [compile ?values special-args]
+ (|do [:let [(&/$Cons ?left (&/$Cons ?right (&/$Nil))) ?values]
+ =left (compile ?left)
+ =right (compile ?right)]
+ (return (str "(" =left " === " =right ")"))))
(do-template [<name> <method>]
(defn <name> [compile ?values special-args]
@@ -132,11 +122,42 @@
(defn <name> [compile ?values special-args]
(|do [:let [(&/$Cons ?x (&/$Nil)) ?values]
=x (compile ?x)]
- (return (str &&rt/LuxRT "." <method> "(" =x ")"))))
+ (return (str &&rt/LuxRT "." <method> "(" =x ")"))
+ ))
^:private compile-int-encode "encodeI64"
^:private compile-nat-encode "encodeN64"
^:private compile-deg-encode "encodeD64"
+
+ ^:private compile-int-decode "decodeI64"
+ ^:private compile-nat-decode "decodeN64"
+ ^:private compile-deg-decode "decodeD64"
+
+ ^:private compile-real-decode "decodeReal"
+
+ ^:private compile-real-hash "hashReal"
+ )
+
+(do-template [<name> <compiler> <value>]
+ (defn <name> [compile ?values special-args]
+ (|do [:let [(&/$Nil) ?values]]
+ (<compiler> <value>)))
+
+ ^:private compile-nat-min-value &&lux/compile-nat 0
+ ^:private compile-nat-max-value &&lux/compile-nat -1
+
+ ^:private compile-int-min-value &&lux/compile-int Long/MIN_VALUE
+ ^:private compile-int-max-value &&lux/compile-int Long/MAX_VALUE
+
+ ^:private compile-deg-min-value &&lux/compile-deg 0
+ ^:private compile-deg-max-value &&lux/compile-deg -1
+
+ ^:private compile-real-min-value &&lux/compile-real (* -1.0 Double/MAX_VALUE)
+ ^:private compile-real-max-value &&lux/compile-real Double/MAX_VALUE
+
+ ^:private compile-real-not-a-number &&lux/compile-real "NaN"
+ ^:private compile-real-positive-infinity &&lux/compile-real "Infinity"
+ ^:private compile-real-negative-infinity &&lux/compile-real "-Infinity"
)
(defn ^:private compile-real-encode [compile ?values special-args]
@@ -166,22 +187,6 @@
;; (.visitLabel $end))]]
;; (return nil)))
-;; (do-template [<name> <instr> <wrapper>]
-;; (defn <name> [compile ?values special-args]
-;; (|do [:let [(&/$Nil) ?values]
-;; ^MethodVisitor *writer* &/get-writer
-;; :let [_ (doto *writer*
-;; <instr>
-;; <wrapper>)]]
-;; (return nil)))
-
-;; ^:private compile-nat-min-value (.visitLdcInsn 0) &&/wrap-long
-;; ^:private compile-nat-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 [<name> <method>]
;; (defn <name> [compile ?values special-args]
;; (|do [:let [(&/$Cons ?x (&/$Cons ?y (&/$Nil))) ?values]
@@ -248,6 +253,26 @@
^:private compile-int-to-nat
)
+(defn ^:private compile-int-to-real [compile ?values special-args]
+ (|do [:let [(&/$Cons ?x (&/$Nil)) ?values]
+ =x (compile ?x)]
+ (return (str "LuxRT.toNumberI64(" =x ")"))))
+
+(defn ^:private compile-real-to-int [compile ?values special-args]
+ (|do [:let [(&/$Cons ?x (&/$Nil)) ?values]
+ =x (compile ?x)]
+ (return (str "LuxRT.fromNumberI64(" =x ")"))))
+
+(defn ^:private compile-deg-to-real [compile ?values special-args]
+ (|do [:let [(&/$Cons ?x (&/$Nil)) ?values]
+ =x (compile ?x)]
+ (return (str "LuxRT.degToReal(" =x ")"))))
+
+(defn ^:private compile-real-to-deg [compile ?values special-args]
+ (|do [:let [(&/$Cons ?x (&/$Nil)) ?values]
+ =x (compile ?x)]
+ (return (str "LuxRT.realToDeg(" =x ")"))))
+
(defn ^:private compile-text-eq [compile ?values special-args]
(|do [:let [(&/$Cons ?x (&/$Cons ?y (&/$Nil))) ?values]
=x (compile ?x)
@@ -260,29 +285,78 @@
=y (compile ?y)]
(return (str =x ".concat(" =y ")"))))
+(do-template [<name> <method>]
+ (defn <name> [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Cons ?part (&/$Nil))) ?values]
+ =text (compile ?text)
+ =part (compile ?part)]
+ (return (str "LuxRT" "." <method> "(" =text "," =part ")"))))
+
+ ^:private compile-text-last-index "lastIndex"
+ ^:private compile-text-index "index"
+ )
+
+(defn ^:private compile-text-clip [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Cons ?from (&/$Cons ?to (&/$Nil)))) ?values]
+ =text (compile ?text)
+ =from (compile ?from)
+ =to (compile ?to)]
+ (return (str "LuxRT.clip(" (str =text "," =from "," =to) ")"))))
+
+(defn ^:private compile-text-replace-all [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Cons ?to-find (&/$Cons ?replace-with (&/$Nil)))) ?values]
+ =text (compile ?text)
+ =to-find (compile ?to-find)
+ =replace-with (compile ?replace-with)]
+ (return (str "LuxRT.replaceAll(" (str =text "," =to-find "," =replace-with) ")"))))
+
+(defn ^:private compile-text-trim [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Nil)) ?values]
+ =text (compile ?text)]
+ (return (str "(" =text ").trim()"))))
+
+(defn ^:private compile-text-size [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Nil)) ?values]
+ =text (compile ?text)]
+ (return (str "LuxRT.fromNumberI64(" =text ".length" ")"))))
+
(defn ^:private compile-char-to-text [compile ?values special-args]
- (|do [:let [(&/$Cons ?x (&/$Nil)) ?values]]
- (compile ?x)))
+ (|do [:let [(&/$Cons ?x (&/$Nil)) ?values]
+ =x (compile ?x)]
+ (return (str "(" =x ").C"))))
-(defn ^:private compile-lux-log! [compile ?values special-args]
+(defn ^:private compile-lux-log [compile ?values special-args]
(|do [:let [(&/$Cons ?message (&/$Nil)) ?values]
=message (compile ?message)]
(return (str "LuxRT.log(" =message ")"))))
+(defn ^:private compile-lux-error [compile ?values special-args]
+ (|do [:let [(&/$Cons ?message (&/$Nil)) ?values]
+ =message (compile ?message)]
+ (return (str "LuxRT.error(" =message ")"))))
+
(defn compile-proc [compile proc-category proc-name ?values special-args]
(case proc-category
- ;; "lux"
- ;; (case proc-name
- ;; "==" (compile-lux-== compile ?values special-args))
+ "lux"
+ (case proc-name
+ "is" (compile-lux-is compile ?values special-args))
"io"
(case proc-name
- "log!" (compile-lux-log! compile ?values special-args))
+ "log" (compile-lux-log compile ?values special-args)
+ "error" (compile-lux-error compile ?values special-args))
"text"
(case proc-name
"=" (compile-text-eq compile ?values special-args)
- "append" (compile-text-append compile ?values special-args))
+ "append" (compile-text-append compile ?values special-args)
+ "clip" (compile-text-clip compile ?values special-args)
+ "index" (compile-text-index compile ?values special-args)
+ "last-index" (compile-text-last-index compile ?values special-args)
+ "size" (compile-text-size compile ?values special-args)
+ "replace-all" (compile-text-replace-all compile ?values special-args)
+ "trim" (compile-text-trim compile ?values special-args)
+ )
;; "bit"
;; (case proc-name
@@ -308,9 +382,9 @@
"=" (compile-nat-eq compile ?values special-args)
"<" (compile-nat-lt compile ?values special-args)
"encode" (compile-nat-encode compile ?values special-args)
- ;; "decode" (compile-nat-decode compile ?values special-args)
- ;; "max-value" (compile-nat-max-value compile ?values special-args)
- ;; "min-value" (compile-nat-min-value compile ?values special-args)
+ "decode" (compile-nat-decode compile ?values special-args)
+ "max-value" (compile-nat-max-value compile ?values special-args)
+ "min-value" (compile-nat-min-value compile ?values special-args)
"to-int" (compile-nat-to-int compile ?values special-args)
;; "to-char" (compile-nat-to-char compile ?values special-args)
)
@@ -325,10 +399,11 @@
"=" (compile-int-eq compile ?values special-args)
"<" (compile-int-lt compile ?values special-args)
"encode" (compile-int-encode compile ?values special-args)
- ;; "decode" (compile-int-decode compile ?values special-args)
- ;; "max-value" (compile-int-max-value compile ?values special-args)
- ;; "min-value" (compile-int-min-value compile ?values special-args)
+ "decode" (compile-int-decode compile ?values special-args)
+ "max-value" (compile-int-max-value compile ?values special-args)
+ "min-value" (compile-int-min-value compile ?values special-args)
"to-nat" (compile-int-to-nat compile ?values special-args)
+ "to-real" (compile-int-to-real compile ?values special-args)
)
"deg"
@@ -341,10 +416,10 @@
"=" (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)
+ "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)
)
@@ -358,10 +433,15 @@
"=" (compile-real-eq compile ?values special-args)
"<" (compile-real-lt compile ?values special-args)
"encode" (compile-real-encode compile ?values special-args)
- ;; "decode" (compile-real-decode compile ?values special-args)
- ;; "max-value" (compile-real-max-value compile ?values special-args)
- ;; "min-value" (compile-real-min-value compile ?values special-args)
- ;; "to-deg" (compile-real-to-deg compile ?values special-args)
+ "decode" (compile-real-decode compile ?values special-args)
+ "max-value" (compile-real-max-value compile ?values special-args)
+ "min-value" (compile-real-min-value compile ?values special-args)
+ "not-a-number" (compile-real-not-a-number compile ?values special-args)
+ "positive-infinity" (compile-real-positive-infinity compile ?values special-args)
+ "negative-infinity" (compile-real-negative-infinity compile ?values special-args)
+ "to-deg" (compile-real-to-deg compile ?values special-args)
+ "to-int" (compile-real-to-int compile ?values special-args)
+ "hash" (compile-real-hash compile ?values special-args)
)
"char"
diff --git a/luxc/src/lux/compiler/js/rt.clj b/luxc/src/lux/compiler/js/rt.clj
index ce5bf5d16..1cb4a6150 100644
--- a/luxc/src/lux/compiler/js/rt.clj
+++ b/luxc/src/lux/compiler/js/rt.clj
@@ -941,16 +941,50 @@
})
(def ^:private i64-methods
- {"makeI64" (str "(function makeI64(high,low) {"
+ {"TWO_PWR_16" "(1 << 16)"
+ "TWO_PWR_32" "((1 << 16) * (1 << 16))"
+ "TWO_PWR_64" "(((1 << 16) * (1 << 16)) * ((1 << 16) * (1 << 16)))"
+ "TWO_PWR_63" "((((1 << 16) * (1 << 16)) * ((1 << 16) * (1 << 16))) / 2)"
+ "getLowBitsUnsigned" (str "(function getLowBitsUnsigned(i64) {"
+ "return (i64.L >= 0) ? i64.L : (LuxRT.TWO_PWR_32 + i64.L);"
+ "})")
+ "toNumberI64" (str "(function toNumberI64(i64) {"
+ "return (i64.H * LuxRT.TWO_PWR_32) + LuxRT.getLowBitsUnsigned(i64);"
+ "})")
+ "fromNumberI64" (str "(function fromNumberI64(num) {"
+ (str "if (isNaN(num)) {"
+ "return LuxRT.ZERO;"
+ "}")
+ (str "else if (num <= -LuxRT.TWO_PWR_63) {"
+ "return LuxRT.MIN_VALUE_I64;"
+ "}")
+ (str "else if ((num + 1) >= LuxRT.TWO_PWR_63) {"
+ "return LuxRT.MAX_VALUE_I64;"
+ "}")
+ (str "else if (num < 0) {"
+ "return LuxRT.negateI64(LuxRT.fromNumberI64(-num));"
+ "}")
+ (str "else {"
+ "return LuxRT.makeI64((num / LuxRT.TWO_PWR_32), (num % LuxRT.TWO_PWR_32));"
+ "}")
+ "})")
+ "makeI64" (str "(function makeI64(high,low) {"
"return { H: (high|0), L: (low|0)};"
"})")
- "MIN_VALUE" "{ H: 0x80000000, L: 0}"
- "ONE" "{ H: 0, L: 1}"
+ "MIN_VALUE_I64" "{ H: (0x80000000|0), L: (0|0)}"
+ "MAX_VALUE_I64" "{ H: (0x7FFFFFFF|0), L: (0xFFFFFFFF|0)}"
+ "ONE" "{ H: (0|0), L: (1|0)}"
+ "ZERO" "{ H: (0|0), L: (0|0)}"
"notI64" (str "(function notI64(i64) {"
"return LuxRT.makeI64(~i64.H,~i64.L);"
"})")
"negateI64" (str "(function negateI64(i64) {"
- "return LuxRT.addI64(LuxRT.notI64(i64),LuxRT.makeI64(0,1));"
+ (str "if(LuxRT.eqI64(LuxRT.MIN_VALUE_I64,i64)) {"
+ "return LuxRT.MIN_VALUE_I64;"
+ "}")
+ (str "else {"
+ "return LuxRT.addI64(LuxRT.notI64(i64),LuxRT.ONE);"
+ "}")
"})")
"eqI64" (str "(function eqI64(l,r) {"
"return (l.H === r.H) && (l.L === r.L);"
@@ -1045,14 +1079,14 @@
;; Special case: L = 0
"return l;"
"}")
- (str "if(LuxRT.eqI64(l,LuxRT.MIN_VALUE)) {"
+ (str "if(LuxRT.eqI64(l,LuxRT.MIN_VALUE_I64)) {"
;; Special case: L = MIN
(str "if(LuxRT.eqI64(r,LuxRT.ONE) || LuxRT.eqI64(r,LuxRT.negateI64(LuxRT.ONE))) {"
;; Special case: L = MIN, R = 1|-1
- "return LuxRT.MIN_VALUE;"
+ "return LuxRT.MIN_VALUE_I64;"
"}"
;; Special case: L = R = MIN
- "else if(LuxRT.eqI64(r,LuxRT.MIN_VALUE)) {"
+ "else if(LuxRT.eqI64(r,LuxRT.MIN_VALUE_I64)) {"
"return LuxRT.ONE;"
"}"
;; Special case: L = MIN
@@ -1073,7 +1107,7 @@
"}")
"}")
"}"
- "else if(LuxRT.eqI64(r,LuxRT.MIN_VALUE)) {"
+ "else if(LuxRT.eqI64(r,LuxRT.MIN_VALUE_I64)) {"
;; Special case: R = MIN
"return LuxRT.makeI64(0,0);"
"}")
@@ -1093,7 +1127,7 @@
"return LuxRT.negateI64(LuxRT.divI64(l,LuxRT.negateI64(r)));"
"}")
;; Common case
- (str "var res = { H: 0, L: 0};"
+ (str "var res = LuxRT.ZERO;"
"var rem = l;"
(str "while(LuxRT.ltI64(r,rem) || LuxRT.eqI64(r,rem)) {"
"var approx = Math.max(1, Math.floor(LuxRT.toNumberI64(rem) / LuxRT.toNumberI64(r)));"
@@ -1124,16 +1158,16 @@
"}")
;; If input < 0
(str "if(input.H < 0) {"
- (str "if(LuxRT.eqI64(input,LuxRT.MIN_VALUE)) {"
+ (str "if(LuxRT.eqI64(input,LuxRT.MIN_VALUE_I64)) {"
"var radix = LuxRT.makeI64(0,10);"
"var div = LuxRT.divI64(input,radix);"
"var rem = LuxRT.subI64(LuxRT.mulI64(div,radix),input);"
"return LuxRT.encodeI64(div).concat(rem.L+'');"
"}")
"}"
- "else {"
- "return '-'.concat(LuxRT.encodeI64(LuxRT.negateI64(input)));"
- "}")
+ (str "else {"
+ "return '-'.concat(LuxRT.encodeI64(LuxRT.negateI64(input)));"
+ "}"))
;; If input > 0
(str "var chunker = LuxRT.makeI64(0,1000000);"
"var rem = input;"
@@ -1176,6 +1210,11 @@
"return '+'.concat(LuxRT.encodeI64(input));"
"}")
"})")
+ "ltN64" (str "(function ltN64(l,r) {"
+ "var li = LuxRT.addI64(l,LuxRT.MIN_VALUE_I64);"
+ "var ri = LuxRT.addI64(r,LuxRT.MIN_VALUE_I64);"
+ "return LuxRT.ltI64(li,ri);"
+ "})")
})
(def ^:private io-methods
@@ -1183,6 +1222,48 @@
"console.log(message);"
(str "return " &&/unit ";")
"})")
+ "error" (str "(function error(message) {"
+ "throw new Error(message);"
+ (str "return null;")
+ "})")
+ })
+
+(def ^:private const-none (str "[0,null," &&/unit "]"))
+(defn ^:private make-some [value]
+ (str "[1,''," value "]"))
+
+(def ^:private text-methods
+ {"index" (str "(function index(text,part) {"
+ "var idx = text.indexOf(part);"
+ (str (str "if(idx === -1) {"
+ "return " const-none ";"
+ "}")
+ (str "else {"
+ (str "return " (make-some "LuxRT.fromNumberI64(idx)") ";")
+ "}"))
+ "})")
+ "lastIndex" (str "(function lastIndex(text,part) {"
+ "var idx = text.lastIndexOf(part);"
+ (str (str "if(idx === -1) {"
+ "return " const-none ";"
+ "}")
+ (str "else {"
+ (str "return " (make-some "LuxRT.fromNumberI64(idx)") ";")
+ "}"))
+ "})")
+ "clip" (str "(function clip(text,from,to) {"
+ "var clip = text.substring(from.L,to.L);"
+ (str (str "if(clip === '') {"
+ "return " const-none ";"
+ "}")
+ (str "else {"
+ "return " (make-some "clip") ";"
+ "}"))
+ "})")
+ "replaceAll" (str "(function replaceAll(text,toFind,replaceWith) {"
+ "var reEscaped = toFind.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');"
+ "return text.replace(new RegExp(reEscaped, 'g'), replaceWith);"
+ "})")
})
(def LuxRT "LuxRT")
@@ -1192,6 +1273,7 @@
:let [rt-object (str "{" (->> (merge adt-methods
i64-methods
n64-methods
+ text-methods
io-methods)
(map (fn [[key val]]
(str key ":" val)))
diff --git a/luxc/src/lux/compiler/jvm/proc/common.clj b/luxc/src/lux/compiler/jvm/proc/common.clj
index 4ed8134fd..c48403e52 100644
--- a/luxc/src/lux/compiler/jvm/proc/common.clj
+++ b/luxc/src/lux/compiler/jvm/proc/common.clj
@@ -162,7 +162,7 @@
^:private compile-bit-unsigned-shift-right Opcodes/LUSHR
)
-(defn ^:private compile-lux-== [compile ?values special-args]
+(defn ^:private compile-lux-is [compile ?values special-args]
(|do [:let [(&/$Cons ?left (&/$Cons ?right (&/$Nil))) ?values]
^MethodVisitor *writer* &/get-writer
_ (compile ?left)
@@ -209,11 +209,11 @@
^:private compile-deg-rem Opcodes/LSUB &&/unwrap-long &&/wrap-long
^:private compile-deg-scale Opcodes/LMUL &&/unwrap-long &&/wrap-long
- ^:private compile-real-add Opcodes/DADD &&/unwrap-double &&/wrap-double
- ^:private compile-real-sub Opcodes/DSUB &&/unwrap-double &&/wrap-double
- ^:private compile-real-mul Opcodes/DMUL &&/unwrap-double &&/wrap-double
- ^:private compile-real-div Opcodes/DDIV &&/unwrap-double &&/wrap-double
- ^:private compile-real-rem Opcodes/DREM &&/unwrap-double &&/wrap-double
+ ^:private compile-real-add Opcodes/DADD &&/unwrap-double &&/wrap-double
+ ^:private compile-real-sub Opcodes/DSUB &&/unwrap-double &&/wrap-double
+ ^:private compile-real-mul Opcodes/DMUL &&/unwrap-double &&/wrap-double
+ ^:private compile-real-div Opcodes/DDIV &&/unwrap-double &&/wrap-double
+ ^:private compile-real-rem Opcodes/DREM &&/unwrap-double &&/wrap-double
)
(do-template [<name> <comp-method>]
@@ -450,6 +450,21 @@
^:private compile-int-to-nat
)
+(do-template [<name> <unwrap> <op> <wrap>]
+ (defn <name> [compile ?values special-args]
+ (|do [:let [(&/$Cons ?input (&/$Nil)) ?values]
+ ^MethodVisitor *writer* &/get-writer
+ _ (compile ?input)
+ :let [_ (doto *writer*
+ <unwrap>
+ (.visitInsn <op>)
+ <wrap>)]]
+ (return nil)))
+
+ ^:private compile-real-to-int &&/unwrap-double Opcodes/D2L &&/wrap-long
+ ^:private compile-int-to-real &&/unwrap-long Opcodes/L2D &&/wrap-double
+ )
+
(defn compile-text-eq [compile ?values special-args]
(|do [:let [(&/$Cons ?x (&/$Cons ?y (&/$Nil))) ?values]
^MethodVisitor *writer* &/get-writer
@@ -473,7 +488,93 @@
(.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "concat" "(Ljava/lang/String;)Ljava/lang/String;"))]]
(return nil)))
-(defn compile-io-log! [compile ?values special-args]
+(defn compile-text-clip [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Cons ?from (&/$Cons ?to (&/$Nil)))) ?values]
+ ^MethodVisitor *writer* &/get-writer
+ _ (compile ?text)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String"))]
+ _ (compile ?from)
+ :let [_ (doto *writer*
+ &&/unwrap-long
+ (.visitInsn Opcodes/L2I))]
+ _ (compile ?to)
+ :let [_ (doto *writer*
+ &&/unwrap-long
+ (.visitInsn Opcodes/L2I))]
+ :let [_ (doto *writer*
+ (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "text_clip" "(Ljava/lang/String;II)[Ljava/lang/Object;"))]]
+ (return nil)))
+
+(do-template [<name> <method>]
+ (defn <name> [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Cons ?part (&/$Nil))) ?values]
+ ^MethodVisitor *writer* &/get-writer
+ _ (compile ?text)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String"))]
+ _ (compile ?part)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String"))]
+ :let [_ (doto *writer*
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" <method> "(Ljava/lang/String;)I"))]
+ :let [$not-found (new Label)
+ $end (new Label)
+ _ (doto *writer*
+ (.visitInsn Opcodes/DUP)
+ (.visitLdcInsn (int -1))
+ (.visitJumpInsn Opcodes/IF_ICMPEQ $not-found)
+ (.visitInsn Opcodes/I2L)
+ &&/wrap-long
+ (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_some" "(Ljava/lang/Object;)Ljava/lang/Object;")
+ (.visitJumpInsn Opcodes/GOTO $end)
+ (.visitLabel $not-found)
+ (.visitInsn Opcodes/POP)
+ (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;")
+ (.visitLabel $end))]]
+ (return nil)))
+
+ ^:private compile-text-index "indexOf"
+ ^:private compile-text-last-index "lastIndexOf"
+ )
+
+(defn ^:private compile-text-size [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Nil)) ?values]
+ ^MethodVisitor *writer* &/get-writer
+ _ (compile ?text)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String")
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "length" "()I")
+ (.visitInsn Opcodes/I2L)
+ &&/wrap-long)]]
+ (return nil)))
+
+(defn ^:private compile-text-replace-all [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Cons ?pattern (&/$Cons ?replacement (&/$Nil)))) ?values]
+ ^MethodVisitor *writer* &/get-writer
+ _ (compile ?text)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String"))]
+ _ (compile ?pattern)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String"))]
+ _ (compile ?replacement)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String"))]
+ :let [_ (doto *writer*
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "replace" "(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;"))]]
+ (return nil)))
+
+(defn ^:private compile-text-trim [compile ?values special-args]
+ (|do [:let [(&/$Cons ?text (&/$Nil)) ?values]
+ ^MethodVisitor *writer* &/get-writer
+ _ (compile ?text)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String")
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "trim" "()Ljava/lang/String;"))]]
+ (return nil)))
+
+(defn compile-io-log [compile ?values special-args]
(|do [:let [(&/$Cons ?x (&/$Nil)) ?values]
^MethodVisitor *writer* &/get-writer
:let [_ (doto *writer*
@@ -485,20 +586,41 @@
(.visitLdcInsn &/unit-tag))]]
(return nil)))
+(defn compile-io-error [compile ?values special-args]
+ (|do [:let [(&/$Cons ?message (&/$Nil)) ?values]
+ ^MethodVisitor *writer* &/get-writer
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/NEW "java/lang/Error")
+ (.visitInsn Opcodes/DUP))]
+ _ (compile ?message)
+ :let [_ (doto *writer*
+ (.visitTypeInsn Opcodes/CHECKCAST "java/lang/String")
+ (.visitMethodInsn Opcodes/INVOKESPECIAL "java/lang/Error" "<init>" "(Ljava/lang/String;)V")
+ (.visitInsn Opcodes/ATHROW))]]
+ (return nil)))
+
(defn compile-proc [compile proc-category proc-name ?values special-args]
(case proc-category
"lux"
(case proc-name
- "==" (compile-lux-== compile ?values special-args))
+ "is" (compile-lux-is compile ?values special-args))
"io"
(case proc-name
- "log!" (compile-io-log! compile ?values special-args))
+ "log" (compile-io-log compile ?values special-args)
+ "error" (compile-io-error compile ?values special-args))
"text"
(case proc-name
"=" (compile-text-eq compile ?values special-args)
- "append" (compile-text-append compile ?values special-args))
+ "append" (compile-text-append compile ?values special-args)
+ "clip" (compile-text-clip compile ?values special-args)
+ "index" (compile-text-index compile ?values special-args)
+ "last-index" (compile-text-last-index compile ?values special-args)
+ "size" (compile-text-size compile ?values special-args)
+ "replace-all" (compile-text-replace-all compile ?values special-args)
+ "trim" (compile-text-trim compile ?values special-args)
+ )
"bit"
(case proc-name
@@ -562,6 +684,7 @@
"=" (compile-int-eq compile ?values special-args)
"<" (compile-int-lt compile ?values special-args)
"to-nat" (compile-int-to-nat compile ?values special-args)
+ "to-real" (compile-int-to-real compile ?values special-args)
"encode" (compile-int-encode compile ?values special-args)
)
@@ -575,6 +698,7 @@
"=" (compile-real-eq compile ?values special-args)
"<" (compile-real-lt compile ?values special-args)
"encode" (compile-real-encode compile ?values special-args)
+ "to-int" (compile-real-to-int compile ?values special-args)
"to-deg" (compile-real-to-deg compile ?values special-args)
)
diff --git a/luxc/src/lux/compiler/jvm/rt.clj b/luxc/src/lux/compiler/jvm/rt.clj
index 1beb9aa21..303d9ae0a 100644
--- a/luxc/src/lux/compiler/jvm/rt.clj
+++ b/luxc/src/lux/compiler/jvm/rt.clj
@@ -1204,6 +1204,33 @@
(.visitEnd))]
nil))
+(defn ^:private compile-LuxRT-text-methods [^ClassWriter =class]
+ (|do [:let [_ (let [$from (new Label)
+ $to (new Label)
+ $handler (new Label)
+ $end (new Label)]
+ (doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "text_clip" "(Ljava/lang/String;II)[Ljava/lang/Object;" nil nil)
+ (.visitCode)
+ (.visitTryCatchBlock $from $to $handler "java/lang/IndexOutOfBoundsException")
+ (.visitLabel $from)
+ (.visitVarInsn Opcodes/ALOAD 0)
+ (.visitVarInsn Opcodes/ILOAD 1)
+ (.visitVarInsn Opcodes/ILOAD 2)
+ (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/String" "substring" "(II)Ljava/lang/String;")
+ (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_some" "(Ljava/lang/Object;)Ljava/lang/Object;")
+ (.visitTypeInsn Opcodes/CHECKCAST "[Ljava/lang/Object;")
+ (.visitJumpInsn Opcodes/GOTO $end)
+ (.visitLabel $to)
+ (.visitLabel $handler)
+ (.visitInsn Opcodes/POP)
+ (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "make_none" "()Ljava/lang/Object;")
+ (.visitTypeInsn Opcodes/CHECKCAST "[Ljava/lang/Object;")
+ (.visitLabel $end)
+ (.visitInsn Opcodes/ARETURN)
+ (.visitMaxs 0 0)
+ (.visitEnd)))]]
+ (return nil)))
+
(def compile-LuxRT-class
(|do [_ (return nil)
:let [full-name &&/lux-utils-class
@@ -1264,6 +1291,7 @@
(compile-LuxRT-pm-methods)
(compile-LuxRT-adt-methods)
(compile-LuxRT-nat-methods)
- (compile-LuxRT-deg-methods))]]
+ (compile-LuxRT-deg-methods)
+ (compile-LuxRT-text-methods))]]
(&&/save-class! (second (string/split &&/lux-utils-class #"/"))
(.toByteArray (doto =class .visitEnd)))))
diff --git a/stdlib/source/lux.lux b/stdlib/source/lux.lux
index 06c0fd2fd..c6018398b 100644
--- a/stdlib/source/lux.lux
+++ b/stdlib/source/lux.lux
@@ -1666,6 +1666,13 @@
(#Cons [[k' v] dict'])
(#Cons [[k' v'] (put k v dict')]))))
+(def:''' #export (log! message)
+ (list [["lux" "doc"] (#TextA "Logs message to standard output.
+
+ Useful for debugging.")])
+ (-> Text Unit)
+ (_lux_proc ["io" "log"] [message]))
+
(def:''' (Text/append x y)
#Nil
(-> Text Text Text)
@@ -2241,13 +2248,6 @@
(-> Bool Bool)
(if x false true))
-(def:''' #export (log! message)
- (list [["lux" "doc"] (#TextA "Logs message to standard output.
-
- Useful for debugging.")])
- (-> Text Unit)
- (_lux_proc ["io" "log!"] [message]))
-
(def:''' (find-macro' modules current-module module name)
#Nil
(-> ($' List (& Text Module))
@@ -2568,7 +2568,7 @@
(macro:' #export (Rec tokens)
(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.
+ ## A name has to be given to the whole type, to use it within its body.
(Rec Self
[Int (List Self)])")])
(_lux_case tokens
@@ -3223,42 +3223,81 @@
(#Some y))))
(def: (last-index-of part text)
- (-> Text Text Int)
- (_lux_proc ["jvm" "i2l"] [(_lux_proc ["jvm" "invokevirtual:java.lang.String:lastIndexOf:java.lang.String"] [text part])]))
+ (-> Text Text (Maybe Nat))
+ (_lux_proc ["text" "last-index"] [text part]))
(def: (index-of part text)
- (-> Text Text Int)
- (_lux_proc ["jvm" "i2l"] [(_lux_proc ["jvm" "invokevirtual:java.lang.String:indexOf:java.lang.String"] [text part])]))
+ (-> Text Text (Maybe Nat))
+ (_lux_proc ["text" "index"] [text part]))
+
+(def: (clip1 from text)
+ (-> Nat Text (Maybe Text))
+ (_lux_proc ["text" "clip"] [text from (_lux_proc ["text" "size"] [text])]))
+
+(def: (clip2 from to text)
+ (-> Nat Nat Text (Maybe Text))
+ (_lux_proc ["text" "clip"] [text from to]))
+
+(def: #export (error! message)
+ {#;doc "## Causes an error, with the given error message.
+ (error! \"OH NO!\")"}
+ (-> Text Bottom)
+ (_lux_proc ["io" "error"] [message]))
-(def: (substring1 idx text)
- (-> Int Text Text)
- (_lux_proc ["jvm" "invokevirtual:java.lang.String:substring:int"] [text (_lux_proc ["jvm" "l2i"] [idx])]))
+(macro: #export (default tokens state)
+ {#;doc "## Allows you to provide a default value that will be used
+ ## if a (Maybe x) value turns out to be #;None.
+ (default 20 (#;Some 10)) => 10
-(def: (substring2 idx1 idx2 text)
- (-> Int Int Text Text)
- (_lux_proc ["jvm" "invokevirtual:java.lang.String:substring:int,int"] [text (_lux_proc ["jvm" "l2i"] [idx1]) (_lux_proc ["jvm" "l2i"] [idx2])]))
+ (default 20 #;None) => 20"}
+ (case tokens
+ (^ (list else maybe))
+ (let [g!temp (: AST [_cursor (#;SymbolS ["" ""])])
+ code (` (case (~ maybe)
+ (#;Some (~ g!temp))
+ (~ g!temp)
+
+ #;None
+ (~ else)))]
+ (#;Right [state (list code)]))
+
+ _
+ (#;Left "Wrong syntax for ?")))
(def: (split-text splitter input)
(-> Text Text (List Text))
- (let [idx (index-of splitter input)]
- (if (i.< 0 idx)
- (#Cons input #Nil)
- (#Cons (substring2 0 idx input)
- (split-text splitter (substring1 (i.+ 1 idx) input))))))
+ (case (index-of splitter input)
+ #;None
+ (#Cons input #Nil)
+
+ (#;Some idx)
+ (#Cons (default (error! "UNDEFINED")
+ (clip2 +0 idx input))
+ (split-text splitter
+ (default (error! "UNDEFINED")
+ (clip1 (n.+ +1 idx) input))))))
(def: (split-module-contexts module)
(-> Text (List Text))
- (#Cons module (let [idx (last-index-of "/" module)]
- (if (i.< 0 idx)
- #Nil
- (split-module-contexts (substring2 0 idx module))))))
+ (#Cons module (case (last-index-of "/" module)
+ #;None
+ #Nil
+
+ (#;Some idx)
+ (split-module-contexts (default (error! "UNDEFINED")
+ (clip2 +0 idx module))))))
(def: (split-module module)
(-> Text (List Text))
- (let [idx (index-of "/" module)]
- (if (i.< 0 idx)
- (list module)
- (list& (substring2 0 idx module) (split-module (substring1 (i.+ 1 idx) module))))))
+ (case (index-of "/" module)
+ #;None
+ (list module)
+
+ (#;Some idx)
+ (list& (default (error! "UNDEFINED")
+ (clip2 +0 idx module))
+ (split-module (default (error! "UNDEFINED")
+ (clip1 (n.+ +1 idx) module))))))
(def: (nth idx xs)
(All [a]
@@ -3881,22 +3920,22 @@
(def: (replace pattern value template)
(-> Text Text Text Text)
- (_lux_proc ["jvm" "invokevirtual:java.lang.String:replace:java.lang.CharSequence,java.lang.CharSequence"] [template pattern value]))
+ (_lux_proc ["text" "replace-all"] [template pattern value]))
(def: (clean-module module)
(-> Text (Lux Text))
(do Monad<Lux>
- [module-name current-module-name]
+ [current-module current-module-name]
(case (split-module module)
(^ (list& "." parts))
- (return (|> (list& module-name parts) (interpose "/") reverse (fold Text/append "")))
+ (return (|> (list& current-module parts) (interpose "/") reverse (fold Text/append "")))
parts
(let [[ups parts'] (split-with (Text/= "..") parts)
num-ups (length ups)]
(if (i.= num-ups 0)
(return module)
- (case (nth num-ups (split-module-contexts module-name))
+ (case (nth num-ups (split-module-contexts current-module))
#None
(fail (Text/append "Can't clean module: " module))
@@ -4378,26 +4417,6 @@
#let [{#module-hash _ #module-aliases _ #defs _ #imports imports #tags _ #types _ #module-anns _ #module-state _} module]]
(wrap (is-member? imports import-name))))
-(macro: #export (default tokens state)
- {#;doc "## Allows you to provide a default value that will be used
- ## if a (Maybe x) value turns out to be #;None.
- (default 20 (#;Some 10)) => 10
-
- (default 20 #;None) => 20"}
- (case tokens
- (^ (list else maybe))
- (let [g!temp (: AST [_cursor (#;SymbolS ["" ""])])
- code (` (case (~ maybe)
- (#;Some (~ g!temp))
- (~ g!temp)
-
- #;None
- (~ else)))]
- (#;Right [state (list code)]))
-
- _
- (#;Left "Wrong syntax for ?")))
-
(def: (read-refer module-name options)
(-> Text (List AST) (Lux Refer))
(do Monad<Lux>
@@ -4790,13 +4809,13 @@
_
(fail "Wrong syntax for ^template")))
-(do-template [<name> <from> <to> <converter>]
+(do-template [<name> <from> <to> <proc>]
[(def: #export (<name> n)
(-> <from> <to>)
- (_lux_proc ["jvm" <converter>] [n]))]
+ (_lux_proc <proc> [n]))]
- [real-to-int Real Int "d2l"]
- [int-to-real Int Real "l2d"]
+ [real-to-int Real Int ["real" "to-int"]]
+ [int-to-real Int Real ["int" "to-real"]]
)
(def: (find-baseline-column ast)
@@ -4874,11 +4893,10 @@
(-> <from> <to>)
(_lux_proc <op> [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-deg ["real" "to-deg"] Real Deg]
- [deg-to-real ["deg" "to-real"] Deg Real]
+ [deg-to-real ["deg" "to-real"] Deg Real]
)
(def: (repeat n x)
@@ -4897,13 +4915,11 @@
(def: (Text/size x)
(-> Text Nat)
- (:! Nat
- (_lux_proc ["jvm" "i2l"]
- [(_lux_proc ["jvm" "invokevirtual:java.lang.String:length:"] [x])])))
+ (_lux_proc ["text" "size"] [x]))
(def: (Text/trim x)
(-> Text Text)
- (_lux_proc ["jvm" "invokevirtual:java.lang.String:trim:"] [x]))
+ (_lux_proc ["text" "trim"] [x]))
(def: (update-cursor [file line column] ast-text)
(-> Cursor Text Cursor)
@@ -5468,7 +5484,7 @@
"This one should fail:"
(is 5 (i.+ 2 3)))}
(All [a] (-> a a Bool))
- (_lux_proc ["lux" "=="] [left right]))
+ (_lux_proc ["lux" "is"] [left right]))
(macro: #export (^@ tokens)
{#;doc (doc "Allows you to simultaneously bind and de-structure a value."
@@ -5514,12 +5530,6 @@
_
(fail "Wrong syntax for :!!")))
-(def: #export (error! message)
- {#;doc (doc "Causes an error, with the given error message."
- (error! "OH NO!"))}
- (-> Text Bottom)
- (_lux_proc ["jvm" "throw"] [(_lux_proc ["jvm" "new:java.lang.Error:java.lang.String"] [message])]))
-
(def: #hidden hack_Text/append
(-> Text Text Text)
Text/append)
@@ -5735,3 +5745,7 @@
(type: #export (<.> f g)
(All [a] (f (g a))))
+
+(def: #export (assume mx)
+ (All [a] (-> (Maybe a) a))
+ (default (undefined) mx))
diff --git a/stdlib/source/lux/data/number.lux b/stdlib/source/lux/data/number.lux
index 998b42ea8..ce0d5f887 100644
--- a/stdlib/source/lux/data/number.lux
+++ b/stdlib/source/lux/data/number.lux
@@ -17,7 +17,7 @@
[ Nat n.=]
[ Int i.=]
- [Deg d.=]
+ [ Deg d.=]
[Real r.=]
)
@@ -29,9 +29,9 @@
(def: > <gt>)
(def: >= <gte>))]
- [ Nat Eq<Nat> n.< n.<= n.> n.>=]
- [ Int Eq<Int> i.< i.<= i.> i.>=]
- [Deg Eq<Deg> d.< d.<= d.> d.>=]
+ [ Nat Eq<Nat> n.< n.<= n.> n.>=]
+ [ Int Eq<Int> i.< i.<= i.> i.>=]
+ [Deg Eq<Deg> d.< d.<= d.> d.>=]
[Real Eq<Real> r.< r.<= r.> r.>=]
)
@@ -100,38 +100,34 @@
(def: top <top>)
(def: bottom <bottom>))]
- [ Nat Ord<Nat> (_lux_proc ["nat" "max-value"] []) (_lux_proc ["nat" "min-value"] [])]
- [ Int Ord<Int> (_lux_proc ["jvm" "getstatic:java.lang.Long:MAX_VALUE"] []) (_lux_proc ["jvm" "getstatic:java.lang.Long:MIN_VALUE"] [])]
- [Real Ord<Real> (_lux_proc ["jvm" "getstatic:java.lang.Double:MAX_VALUE"] []) (_lux_proc ["jvm" "getstatic:java.lang.Double:MIN_VALUE"] [])]
- [Deg Ord<Deg> (_lux_proc ["deg" "max-value"] []) (_lux_proc ["deg" "min-value"] [])])
+ [ Nat Ord<Nat> (_lux_proc [ "nat" "max-value"] []) (_lux_proc [ "nat" "min-value"] [])]
+ [ Int Ord<Int> (_lux_proc [ "int" "max-value"] []) (_lux_proc [ "int" "min-value"] [])]
+ [Real Ord<Real> (_lux_proc ["real" "max-value"] []) (_lux_proc ["real" "min-value"] [])]
+ [ Deg Ord<Deg> (_lux_proc [ "deg" "max-value"] []) (_lux_proc [ "deg" "min-value"] [])])
(do-template [<name> <type> <unit> <append>]
[(struct: #export <name> (Monoid <type>)
(def: unit <unit>)
(def: (append x y) (<append> x y)))]
- [ Add@Monoid<Nat> Nat +0 n.+]
- [ Mul@Monoid<Nat> Nat +1 n.*]
+ [ Add@Monoid<Nat> Nat +0 n.+]
+ [ Mul@Monoid<Nat> Nat +1 n.*]
[ Max@Monoid<Nat> Nat (:: Interval<Nat> bottom) n.max]
[ Min@Monoid<Nat> Nat (:: Interval<Nat> top) n.min]
- [ Add@Monoid<Int> Int 0 i.+]
- [ Mul@Monoid<Int> Int 1 i.*]
+ [ Add@Monoid<Int> Int 0 i.+]
+ [ Mul@Monoid<Int> Int 1 i.*]
[ Max@Monoid<Int> Int (:: Interval<Int> bottom) i.max]
[ Min@Monoid<Int> Int (:: Interval<Int> top) i.min]
- [Add@Monoid<Real> Real 0.0 r.+]
- [Mul@Monoid<Real> Real 1.0 r.*]
+ [Add@Monoid<Real> Real 0.0 r.+]
+ [Mul@Monoid<Real> Real 1.0 r.*]
[Max@Monoid<Real> Real (:: Interval<Real> bottom) r.max]
[Min@Monoid<Real> Real (:: Interval<Real> top) r.min]
- [Add@Monoid<Deg> Deg (:: Interval<Deg> bottom) d.+]
- [Mul@Monoid<Deg> Deg (:: Interval<Deg> top) d.*]
- [Max@Monoid<Deg> Deg (:: Interval<Deg> bottom) d.max]
- [Min@Monoid<Deg> Deg (:: Interval<Deg> top) d.min]
+ [ Add@Monoid<Deg> Deg (:: Interval<Deg> bottom) d.+]
+ [ Mul@Monoid<Deg> Deg (:: Interval<Deg> top) d.*]
+ [ Max@Monoid<Deg> Deg (:: Interval<Deg> bottom) d.max]
+ [ Min@Monoid<Deg> Deg (:: Interval<Deg> top) d.min]
)
-(def: (text.replace pattern value template)
- (-> Text Text Text Text)
- (_lux_proc ["jvm" "invokevirtual:java.lang.String:replace:java.lang.CharSequence,java.lang.CharSequence"] [template pattern value]))
-
(do-template [<type> <encoder> <decoder> <error>]
[(struct: #export _ (Codec Text <type>)
(def: (encode x)
@@ -145,26 +141,10 @@
#;None
(#;Left <error>))))]
- [Nat ["nat" "encode"] ["nat" "decode"] "Couldn't decode Nat"]
- [Deg ["deg" "encode"] ["deg" "decode"] "Couldn't decode Deg"]
- )
-
-(def: clean-number
- (-> Text Text)
- (text.replace "_" ""))
-
-(do-template [<type> <encode> <decode> <error>]
- [(struct: #export _ (Codec Text <type>)
- (def: (encode x)
- (_lux_proc ["jvm" <encode>] [x]))
-
- (def: (decode input)
- (_lux_proc ["jvm" "try"]
- [(#;Right (_lux_proc ["jvm" <decode>] [(clean-number input)]))
- (lambda [e] (#;Left <error>))])))]
-
- [ Int "invokevirtual:java.lang.Object:toString:" "invokestatic:java.lang.Long:parseLong:java.lang.String" "Couldn't parse Int"]
- [Real "invokevirtual:java.lang.Object:toString:" "invokestatic:java.lang.Double:parseDouble:java.lang.String" "Couldn't parse Real"]
+ [ Nat [ "nat" "encode"] [ "nat" "decode"] "Couldn't decode Nat"]
+ [ Int [ "int" "encode"] [ "int" "decode"] "Couldn't decode Int"]
+ [ Deg [ "deg" "encode"] [ "deg" "decode"] "Couldn't decode Deg"]
+ [Real ["real" "encode"] ["real" "decode"] "Couldn't decode Real"]
)
(struct: #export _ (Hash Nat)
@@ -178,13 +158,24 @@
(struct: #export _ (Hash Real)
(def: eq Eq<Real>)
- (def: hash
- (|>. (:: Codec<Text,Real> encode)
- []
- (_lux_proc ["jvm" "invokevirtual:java.lang.Object:hashCode:"])
- []
- (_lux_proc ["jvm" "i2l"])
- int-to-nat)))
+ (def: (hash value)
+ (_lux_proc ["real" "hash"] [value])))
+
+(do-template [<name> <const> <doc>]
+ [(def: #export <name>
+ {#;doc <doc>}
+ Real
+ (_lux_proc ["real" <const>] []))]
+
+ [not-a-number "not-a-number" "Not-a-number."]
+ [positive-infinity "positive-infinity" "Positive infinity."]
+ [negative-infinity "negative-infinity" "Negative infinity."]
+ )
+
+(def: #export (not-a-number? number)
+ {#;doc "Tests whether a real is actually not-a-number."}
+ (-> Real Bool)
+ (not (r.= number number)))
## [Values & Syntax]
(do-template [<struct> <to-proc> <radix> <macro> <error> <doc>]
@@ -221,19 +212,3 @@
(doc "Given syntax for a hexadecimal number, generates a Nat."
(hex "deadBEEF"))]
)
-
-(do-template [<name> <field> <doc>]
- [(def: #export <name>
- {#;doc <doc>}
- Real
- (_lux_proc ["jvm" <field>] []))]
-
- [nan "getstatic:java.lang.Double:NaN" "Not-a-number."]
- [+inf "getstatic:java.lang.Double:POSITIVE_INFINITY" "Positive infinity."]
- [-inf "getstatic:java.lang.Double:NEGATIVE_INFINITY" "Negative infinity."]
- )
-
-(def: #export (nan? number)
- {#;doc "Tests whether a real is actually not-a-number."}
- (-> Real Bool)
- (not (r.= number number)))
diff --git a/stdlib/source/lux/data/text.lux b/stdlib/source/lux/data/text.lux
index bec6d7d2b..9375d6876 100644
--- a/stdlib/source/lux/data/text.lux
+++ b/stdlib/source/lux/data/text.lux
@@ -33,7 +33,7 @@
[trim "invokevirtual:java.lang.String:trim:"]
)
-(def: #export (sub from to x)
+(def: #export (clip from to x)
(-> Nat Nat Text (Maybe Text))
(if (and (n.< to from)
(n.<= (size x) to))
@@ -43,9 +43,9 @@
(_lux_proc ["jvm" "l2i"] [(nat-to-int to)])]))
#;None))
-(def: #export (sub' from x)
+(def: #export (clip' from x)
(-> Nat Text (Maybe Text))
- (sub from (size x) x))
+ (clip from (size x) x))
(def: #export (replace pattern value template)
(-> Text Text Text Text)
@@ -158,7 +158,7 @@
(def: (decode input)
(if (and (starts-with? "\"" input)
(ends-with? "\"" input))
- (case (sub +1 (n.dec (size input)) input)
+ (case (clip +1 (n.dec (size input)) input)
(#;Some input')
(|> input'
(replace "\\\\" "\\")
diff --git a/stdlib/source/lux/math/complex.lux b/stdlib/source/lux/math/complex.lux
index eae4fbe55..87b1a7d18 100644
--- a/stdlib/source/lux/math/complex.lux
+++ b/stdlib/source/lux/math/complex.lux
@@ -38,9 +38,9 @@
(def: #export zero Complex (complex 0.0 0.0))
-(def: #export (nan? complex)
- (or (number;nan? (get@ #real complex))
- (number;nan? (get@ #imaginary complex))))
+(def: #export (not-a-number? complex)
+ (or (number;not-a-number? (get@ #real complex))
+ (number;not-a-number? (get@ #imaginary complex))))
(def: #export (c.= param input)
(-> Complex Complex Bool)
@@ -317,7 +317,7 @@
(def: (decode input)
(case (do Monad<Maybe>
- [input' (text;sub +1 (n.- +1 (text;size input)) input)]
+ [input' (text;clip +1 (n.- +1 (text;size input)) input)]
(text;split-with "," input'))
#;None
(#;Left (Text/append "Wrong syntax for complex numbers: " input))
diff --git a/stdlib/test/test/lux.lux b/stdlib/test/test/lux.lux
index 9516ae317..92ed5e2ca 100644
--- a/stdlib/test/test/lux.lux
+++ b/stdlib/test/test/lux.lux
@@ -115,10 +115,10 @@
(|> x' (/ y) (* y) (= x'))))
))]
- ["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]
- ["Deg" R;deg d.= d.+ d.- d.* d./ d.% d.> .0 (_lux_proc ["deg" "max-value"] []) (_lux_proc ["deg" "max-value"] []) %f id id]
+ ["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]
+ ["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 -> <- = <cap> %a %z]
@@ -128,10 +128,10 @@
(assert ""
(|> value -> <- (= value))))]
- ["Int->Nat" R;int int-to-nat nat-to-int i.= (i.% 1000000) %i %n]
- ["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]
+ ["Int->Nat" R;int int-to-nat nat-to-int i.= (i.% 1000000) %i %n]
+ ["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-deg deg-to-real r.= (r.% 1.0) %r %f]
)
diff --git a/stdlib/test/test/lux/data/text.lux b/stdlib/test/test/lux/data/text.lux
index fd847001e..8ddd27a7c 100644
--- a/stdlib/test/test/lux/data/text.lux
+++ b/stdlib/test/test/lux/data/text.lux
@@ -77,10 +77,10 @@
_
false))
- (|> [(&;sub +0 sizeL sample)
- (&;sub sizeL (&;size sample) sample)
- (&;sub' sizeL sample)
- (&;sub' +0 sample)]
+ (|> [(&;clip +0 sizeL sample)
+ (&;clip sizeL (&;size sample) sample)
+ (&;clip' sizeL sample)
+ (&;clip' +0 sample)]
(case> [(#;Right _l) (#;Right _r) (#;Right _r') (#;Right _f)]
(and (= sampleL _l)
(= sampleR _r)
diff --git a/stdlib/test/test/lux/math/complex.lux b/stdlib/test/test/lux/math/complex.lux
index 04ebcb3c0..f965f9214 100644
--- a/stdlib/test/test/lux/math/complex.lux
+++ b/stdlib/test/test/lux/math/complex.lux
@@ -54,8 +54,8 @@
(r.= imaginary (get@ #&;imaginary r+i)))))
(assert "If either the real part or the imaginary part is NaN, the composite is NaN."
- (and (&;nan? (&;complex number;nan imaginary))
- (&;nan? (&;complex real number;nan))))
+ (and (&;not-a-number? (&;complex number;not-a-number imaginary))
+ (&;not-a-number? (&;complex real number;not-a-number))))
))
(test: "Absolute value"
@@ -69,14 +69,14 @@
(r.>= (r/abs imaginary) abs))))
(assert "The absolute value of a complex number involving a NaN on either dimension, results in a NaN value."
- (and (number;nan? (get@ #&;real (&;c.abs (&;complex number;nan imaginary))))
- (number;nan? (get@ #&;real (&;c.abs (&;complex real number;nan))))))
+ (and (number;not-a-number? (get@ #&;real (&;c.abs (&;complex number;not-a-number imaginary))))
+ (number;not-a-number? (get@ #&;real (&;c.abs (&;complex real number;not-a-number))))))
(assert "The absolute value of a complex number involving an infinity on either dimension, results in an infinite value."
- (and (r.= number;+inf (get@ #&;real (&;c.abs (&;complex number;+inf imaginary))))
- (r.= number;+inf (get@ #&;real (&;c.abs (&;complex real number;+inf))))
- (r.= number;+inf (get@ #&;real (&;c.abs (&;complex number;-inf imaginary))))
- (r.= number;+inf (get@ #&;real (&;c.abs (&;complex real number;-inf))))))
+ (and (r.= number;positive-infinity (get@ #&;real (&;c.abs (&;complex number;positive-infinity imaginary))))
+ (r.= number;positive-infinity (get@ #&;real (&;c.abs (&;complex real number;positive-infinity))))
+ (r.= number;positive-infinity (get@ #&;real (&;c.abs (&;complex number;negative-infinity imaginary))))
+ (r.= number;positive-infinity (get@ #&;real (&;c.abs (&;complex real number;negative-infinity))))))
))
(test: "Addidion, substraction, multiplication and division"