aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/host/js.lux26
-rw-r--r--stdlib/source/lux/tool/compiler/phase/extension.lux3
-rw-r--r--stdlib/source/lux/tool/compiler/phase/translation/js/extension.lux15
-rw-r--r--stdlib/source/lux/tool/compiler/phase/translation/js/extension/common.lux231
-rw-r--r--stdlib/source/lux/tool/compiler/phase/translation/js/extension/host.lux120
-rw-r--r--stdlib/source/lux/tool/compiler/phase/translation/js/primitive.lux10
-rw-r--r--stdlib/source/lux/tool/compiler/phase/translation/js/runtime.lux48
-rw-r--r--stdlib/source/lux/tool/compiler/phase/translation/scheme/extension/common.jvm.lux8
-rw-r--r--stdlib/source/test/lux.lux5
9 files changed, 441 insertions, 25 deletions
diff --git a/stdlib/source/lux/host/js.lux b/stdlib/source/lux/host/js.lux
index b297be69a..e61ce7985 100644
--- a/stdlib/source/lux/host/js.lux
+++ b/stdlib/source/lux/host/js.lux
@@ -29,16 +29,16 @@
(`` (type: #export <type> (|> Any <brand> (~~ (template.splice <super>+)))))]
[Expression Expression' [Code]]
- [Location Location' [Expression' Code]]
+ [Computation Computation' [Expression' Code]]
+ [Location Location' [Computation' Expression' Code]]
)
(do-template [<type> <brand> <super>+]
[(abstract: #export <brand> {} Any)
(`` (type: #export <type> (|> <brand> (~~ (template.splice <super>+)))))]
- [Var Var' [Location' Expression' Code]]
- [Access Access' [Location' Expression' Code]]
- [Computation Computation' [Expression' Code]]
+ [Var Var' [Location' Computation' Expression' Code]]
+ [Access Access' [Location' Computation' Expression' Code]]
[Statement Statement' [Code]]
)
@@ -109,7 +109,7 @@
(:abstraction (format (:representation object) "." field)))
(def: #export (do method inputs object)
- (-> Text (List Expression) Expression Access)
+ (-> Text (List Expression) Expression Computation)
(|> (format (:representation (..the method object))
(|> inputs
(list/map ..code)
@@ -131,6 +131,12 @@
(-> Text Var)
(|>> :abstraction))
+ (def: #export (, pre post)
+ (-> Expression Expression Computation)
+ (|> (format (:representation pre) ", " (:representation post))
+ ..argument
+ :abstraction))
+
(def: #export (then pre post)
(-> Statement Statement Statement)
(:abstraction (format (text.suffix ..statement-suffix
@@ -260,6 +266,16 @@
..argument
:abstraction))
+ (def: #export (new constructor inputs)
+ (-> Expression (List Expression) Computation)
+ (|> (format "new " (:representation constructor)
+ (|> inputs
+ (list/map ..code)
+ (text.join-with ..argument-separator)
+ ..argument))
+ ..argument
+ :abstraction))
+
(def: #export statement
(-> Expression Statement)
(|>> :transmutation))
diff --git a/stdlib/source/lux/tool/compiler/phase/extension.lux b/stdlib/source/lux/tool/compiler/phase/extension.lux
index fd54d54b4..86b2e6b38 100644
--- a/stdlib/source/lux/tool/compiler/phase/extension.lux
+++ b/stdlib/source/lux/tool/compiler/phase/extension.lux
@@ -58,6 +58,9 @@
["Expected" (%n arity)]
["Actual" (%n args)]))
+(exception: #export (incorrect-syntax {name Name})
+ (ex.report ["Extension" (%t name)]))
+
(def: #export (install name handler)
(All [s i o]
(-> Text (Handler s i o) (Operation s i o Any)))
diff --git a/stdlib/source/lux/tool/compiler/phase/translation/js/extension.lux b/stdlib/source/lux/tool/compiler/phase/translation/js/extension.lux
new file mode 100644
index 000000000..a40b4953f
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/translation/js/extension.lux
@@ -0,0 +1,15 @@
+(.module:
+ [lux #*
+ [data
+ [collection
+ ["." dictionary]]]]
+ [//
+ [runtime (#+ Bundle)]]
+ [/
+ ["." common]
+ ["." host]])
+
+(def: #export bundle
+ Bundle
+ (|> common.bundle
+ (dictionary.merge host.bundle)))
diff --git a/stdlib/source/lux/tool/compiler/phase/translation/js/extension/common.lux b/stdlib/source/lux/tool/compiler/phase/translation/js/extension/common.lux
new file mode 100644
index 000000000..3cf3fbc27
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/translation/js/extension/common.lux
@@ -0,0 +1,231 @@
+(.module:
+ [lux #*
+ [control
+ ["." monad (#+ do)]
+ ["ex" exception (#+ exception:)]]
+ [data
+ ["e" error]
+ ["." product]
+ [number (#+ hex)]
+ [collection
+ ["." list ("#/." functor)]
+ ["." dictionary]]]
+ ["." macro (#+ with-gensyms)
+ ["." code]
+ ["s" syntax (#+ syntax:)]]
+ [host (#+ import:)
+ ["_" js (#+ Expression Computation)]]]
+ [///
+ ["///." runtime (#+ Operation Phase Handler Bundle)]
+ ["///." primitive]
+ ["//." ///
+ ["." synthesis (#+ Synthesis)]
+ ["." extension
+ ["." bundle]]]])
+
+(syntax: (Vector {size s.nat} elemT)
+ (wrap (list (` [(~+ (list.repeat size elemT))]))))
+
+(type: #export Nullary (-> (Vector 0 Expression) Computation))
+(type: #export Unary (-> (Vector 1 Expression) Computation))
+(type: #export Binary (-> (Vector 2 Expression) Computation))
+(type: #export Trinary (-> (Vector 3 Expression) Computation))
+(type: #export Variadic (-> (List Expression) Computation))
+
+(syntax: (arity: {name s.local-identifier} {arity s.nat})
+ (with-gensyms [g!_ g!extension g!name g!phase g!inputs]
+ (do @
+ [g!input+ (monad.seq @ (list.repeat arity (macro.gensym "input")))]
+ (wrap (list (` (def: #export ((~ (code.local-identifier name)) (~ g!extension))
+ (-> (-> (..Vector (~ (code.nat arity)) Expression) Computation)
+ Handler)
+ (function ((~ g!_) (~ g!name) (~ g!phase) (~ g!inputs))
+ (case (~ g!inputs)
+ (^ (list (~+ g!input+)))
+ (do /////.monad
+ [(~+ (|> g!input+
+ (list/map (function (_ g!input)
+ (list g!input (` ((~ g!phase) (~ g!input))))))
+ list.concat))]
+ ((~' wrap) ((~ g!extension) [(~+ g!input+)])))
+
+ (~' _)
+ (/////.throw extension.incorrect-arity [(~ g!name) 1 (list.size (~ g!inputs))]))))))))))
+
+(arity: nullary 0)
+(arity: unary 1)
+(arity: binary 2)
+(arity: trinary 3)
+
+(def: #export (variadic extension)
+ (-> Variadic Handler)
+ (function (_ extension-name)
+ (function (_ phase inputsS)
+ (do /////.monad
+ [inputsI (monad.map @ phase inputsS)]
+ (wrap (extension inputsI))))))
+
+## [Procedures]
+## [[Bits]]
+(do-template [<name> <op>]
+ [(def: (<name> [subjectJS paramJS])
+ Binary
+ (<op> subjectJS (///runtime.i64//to-number paramJS)))]
+
+ [bit//left-shift ///runtime.i64//left-shift]
+ [bit//arithmetic-right-shift ///runtime.i64//arithmetic-right-shift]
+ [bit//logical-right-shift ///runtime.i64//logic-right-shift]
+ )
+
+## [[Numbers]]
+(import: #long java/lang/Double
+ (#static MIN_VALUE Double)
+ (#static MAX_VALUE Double))
+
+(do-template [<name> <const>]
+ [(def: (<name> _)
+ Nullary
+ (///primitive.f64 <const>))]
+
+ [frac//smallest (java/lang/Double::MIN_VALUE)]
+ [frac//min (f/* -1.0 (java/lang/Double::MAX_VALUE))]
+ [frac//max (java/lang/Double::MAX_VALUE)]
+ )
+
+(def: frac//decode
+ Unary
+ (|>> list
+ (_.apply/* (_.var "parseFloat"))
+ _.return
+ (_.closure (list))
+ ///runtime.lux//try))
+
+(def: int//char
+ Unary
+ (|>> ///runtime.i64//to-number
+ (list)
+ (_.apply/* (_.var "String.fromCharCode"))))
+
+## [[Text]]
+(def: (text//concat [subjectJS paramJS])
+ Binary
+ (|> subjectJS (_.do "concat" (list paramJS))))
+
+(do-template [<name> <runtime>]
+ [(def: (<name> [subjectJS paramJS extraJS])
+ Trinary
+ (<runtime> subjectJS paramJS extraJS))]
+
+ [text//clip ///runtime.text//clip]
+ [text//index ///runtime.text//index]
+ )
+
+## [[IO]]
+(def: (io//log messageJS)
+ Unary
+ ($_ _.,
+ (///runtime.io//log messageJS)
+ ///runtime.unit))
+
+(def: (io//exit codeJS)
+ Unary
+ (let [@@process (_.var "process")
+ @@window (_.var "window")
+ @@location (_.var "location")]
+ ($_ _.or
+ ($_ _.and
+ (_.not (_.= _.undefined (_.type-of @@process)))
+ (_.the "exit" @@process)
+ (_.do "exit" (list (///runtime.i64//to-number codeJS)) @@process))
+ (_.do "close" (list) @@window)
+ (_.do "reload" (list) @@location))))
+
+(def: (io//current-time _)
+ Nullary
+ (|> (_.new (_.var "Date") (list))
+ (_.do "getTime" (list))
+ ///runtime.i64//from-number))
+
+## [Bundles]
+(def: lux-procs
+ Bundle
+ (|> bundle.empty
+ (bundle.install "is" (binary (product.uncurry _.=)))
+ (bundle.install "try" (unary ///runtime.lux//try))))
+
+(def: bit-procs
+ Bundle
+ (<| (bundle.prefix "bit")
+ (|> bundle.empty
+ (bundle.install "and" (binary (product.uncurry ///runtime.i64//and)))
+ (bundle.install "or" (binary (product.uncurry ///runtime.i64//or)))
+ (bundle.install "xor" (binary (product.uncurry ///runtime.i64//xor)))
+ (bundle.install "left-shift" (binary bit//left-shift))
+ (bundle.install "logical-right-shift" (binary bit//logical-right-shift))
+ (bundle.install "arithmetic-right-shift" (binary bit//arithmetic-right-shift))
+ )))
+
+(def: int-procs
+ Bundle
+ (<| (bundle.prefix "int")
+ (|> bundle.empty
+ (bundle.install "+" (binary (product.uncurry ///runtime.i64//+)))
+ (bundle.install "-" (binary (product.uncurry ///runtime.i64//-)))
+ (bundle.install "*" (binary (product.uncurry ///runtime.i64//*)))
+ (bundle.install "/" (binary (product.uncurry ///runtime.i64///)))
+ (bundle.install "%" (binary (product.uncurry ///runtime.i64//%)))
+ (bundle.install "=" (binary (product.uncurry ///runtime.i64//=)))
+ (bundle.install "<" (binary (product.uncurry ///runtime.i64//<)))
+ (bundle.install "to-frac" (unary ///runtime.i64//to-number))
+ (bundle.install "char" (unary int//char)))))
+
+(def: frac-procs
+ Bundle
+ (<| (bundle.prefix "frac")
+ (|> bundle.empty
+ (bundle.install "+" (binary (product.uncurry _.+)))
+ (bundle.install "-" (binary (product.uncurry _.-)))
+ (bundle.install "*" (binary (product.uncurry _.*)))
+ (bundle.install "/" (binary (product.uncurry _./)))
+ (bundle.install "%" (binary (product.uncurry _.%)))
+ (bundle.install "=" (binary (product.uncurry _.=)))
+ (bundle.install "<" (binary (product.uncurry _.<)))
+ (bundle.install "smallest" (nullary frac//smallest))
+ (bundle.install "min" (nullary frac//min))
+ (bundle.install "max" (nullary frac//max))
+ (bundle.install "to-int" (unary ///runtime.i64//from-number))
+ (bundle.install "encode" (unary (_.do "toString" (list))))
+ (bundle.install "decode" (unary frac//decode)))))
+
+(def: text-procs
+ Bundle
+ (<| (bundle.prefix "text")
+ (|> bundle.empty
+ (bundle.install "=" (binary (product.uncurry _.=)))
+ (bundle.install "<" (binary (product.uncurry _.<)))
+ (bundle.install "concat" (binary text//concat))
+ (bundle.install "index" (trinary text//index))
+ (bundle.install "size" (unary (_.the "length")))
+ (bundle.install "char" (binary (product.uncurry ///runtime.text//char)))
+ (bundle.install "clip" (trinary text//clip))
+ )))
+
+(def: io-procs
+ Bundle
+ (<| (bundle.prefix "io")
+ (|> bundle.empty
+ (bundle.install "log" (unary io//log))
+ (bundle.install "error" (unary ///runtime.io//error))
+ (bundle.install "exit" (unary io//exit))
+ (bundle.install "current-time" (nullary io//current-time)))))
+
+(def: #export bundle
+ Bundle
+ (<| (bundle.prefix "lux")
+ (|> lux-procs
+ (dictionary.merge bit-procs)
+ (dictionary.merge int-procs)
+ (dictionary.merge frac-procs)
+ (dictionary.merge text-procs)
+ (dictionary.merge io-procs)
+ )))
diff --git a/stdlib/source/lux/tool/compiler/phase/translation/js/extension/host.lux b/stdlib/source/lux/tool/compiler/phase/translation/js/extension/host.lux
new file mode 100644
index 000000000..637cadc5f
--- /dev/null
+++ b/stdlib/source/lux/tool/compiler/phase/translation/js/extension/host.lux
@@ -0,0 +1,120 @@
+(.module:
+ [lux #*
+ [control
+ ["." monad (#+ do)]]
+ [data
+ ["." product]
+ [collection
+ ["." dictionary]]]
+ [host
+ ["_" js]]]
+ [//
+ ["." common (#+ Nullary Binary Trinary Variadic)]
+ [//
+ ["///." runtime (#+ Handler Bundle)]
+ ["//." ///
+ ["." synthesis]
+ ["." extension
+ ["." bundle]]]]])
+
+(do-template [<name> <js>]
+ [(def: (<name> _) Nullary <js>)]
+
+ [js//null _.null]
+ [js//undefined _.undefined]
+ [js//object (_.object (list))]
+ )
+
+(def: (js//global name translate inputs)
+ Handler
+ (case inputs
+ (^ (list (synthesis.text global)))
+ (:: /////.monad wrap (_.var global))
+
+ _
+ (/////.throw extension.incorrect-syntax name)))
+
+(def: (js//call name translate inputs)
+ Handler
+ (case inputs
+ (^ (list& functionS argsS+))
+ (do /////.monad
+ [functionJS (translate functionS)
+ argsJS+ (monad.map @ translate argsS+)]
+ (wrap (_.apply/* functionJS argsJS+)))
+
+ _
+ (/////.throw extension.incorrect-syntax name)))
+
+(def: js
+ Bundle
+ (|> bundle.empty
+ (bundle.install "null" (common.nullary js//null))
+ (bundle.install "undefined" (common.nullary js//undefined))
+ (bundle.install "object" (common.nullary js//object))
+ (bundle.install "array" (common.variadic _.array))
+ (bundle.install "global" js//global)
+ (bundle.install "call" js//call)))
+
+(def: (object//new name translate inputs)
+ Handler
+ (case inputs
+ (^ (list& constructorS argsS+))
+ (do /////.monad
+ [constructorJS (translate constructorS)
+ argsJS+ (monad.map @ translate argsS+)]
+ (wrap (_.new constructorJS argsJS+)))
+
+ _
+ (/////.throw extension.incorrect-syntax name)))
+
+(def: (object//call name translate inputs)
+ Handler
+ (case inputs
+ (^ (list& objectS methodS argsS+))
+ (do /////.monad
+ [objectJS (translate objectS)
+ methodJS (translate methodS)
+ argsJS+ (monad.map @ translate argsS+)]
+ (wrap (|> objectJS
+ (_.at methodJS)
+ (_.do "apply" (list& objectJS argsJS+)))))
+
+ _
+ (/////.throw extension.incorrect-syntax name)))
+
+(def: (object//set [fieldJS valueJS objectJS])
+ Trinary
+ (///runtime.js//set objectJS fieldJS valueJS))
+
+(def: object
+ Bundle
+ (<| (bundle.prefix "object")
+ (|> bundle.empty
+ (bundle.install "new" object//new)
+ (bundle.install "call" object//call)
+ (bundle.install "read" (common.binary (product.uncurry ///runtime.js//get)))
+ (bundle.install "write" (common.trinary object//set))
+ (bundle.install "delete" (common.binary (product.uncurry ///runtime.js//delete)))
+ )))
+
+(def: (array//write [indexJS valueJS arrayJS])
+ Trinary
+ (///runtime.array//write indexJS valueJS arrayJS))
+
+(def: array
+ Bundle
+ (<| (bundle.prefix "array")
+ (|> bundle.empty
+ (bundle.install "read" (common.binary (product.uncurry ///runtime.array//read)))
+ (bundle.install "write" (common.trinary array//write))
+ (bundle.install "delete" (common.binary (product.uncurry ///runtime.array//delete)))
+ (bundle.install "length" (common.unary (_.the "length")))
+ )))
+
+(def: #export bundle
+ Bundle
+ (<| (bundle.prefix "js")
+ (|> ..js
+ (dictionary.merge ..object)
+ (dictionary.merge ..array))))
diff --git a/stdlib/source/lux/tool/compiler/phase/translation/js/primitive.lux b/stdlib/source/lux/tool/compiler/phase/translation/js/primitive.lux
index f2bee19c5..ff72b1ac6 100644
--- a/stdlib/source/lux/tool/compiler/phase/translation/js/primitive.lux
+++ b/stdlib/source/lux/tool/compiler/phase/translation/js/primitive.lux
@@ -7,12 +7,12 @@
["." i64]
["." frac]]]
[host
- ["_" js (#+ Expression)]]]
+ ["_" js (#+ Computation)]]]
[//
["//." runtime]])
(def: #export bit
- (-> Bit Expression)
+ (-> Bit Computation)
_.boolean)
(def: high
@@ -25,12 +25,12 @@
(|>> (i64.and mask))))
(def: #export (i64 value)
- (-> (I64 Any) Expression)
+ (-> (I64 Any) Computation)
(//runtime.i64//new (|> value ..high .int _.i32)
(|> value ..low .int _.i32)))
(def: #export f64
- (-> Frac Expression)
+ (-> Frac Computation)
(|>> (cond> [(f/= frac.positive-infinity)]
[(new> _.positive-infinity [])]
@@ -44,5 +44,5 @@
[_.number])))
(def: #export text
- (-> Text Expression)
+ (-> Text Computation)
_.string)
diff --git a/stdlib/source/lux/tool/compiler/phase/translation/js/runtime.lux b/stdlib/source/lux/tool/compiler/phase/translation/js/runtime.lux
index c8e86dcb5..a7b8a5a05 100644
--- a/stdlib/source/lux/tool/compiler/phase/translation/js/runtime.lux
+++ b/stdlib/source/lux/tool/compiler/phase/translation/js/runtime.lux
@@ -149,8 +149,7 @@
(runtime: (lux//program-args)
(with-vars [process output idx]
- (_.if (_.and (_.not (_.= (_.type-of process)
- _.undefined))
+ (_.if (_.and (|> process _.type-of (_.= _.undefined) _.not)
(|> process (_.the "argv")))
($_ _.then
(_.define output ..none)
@@ -671,9 +670,11 @@
(runtime: (js//get object field)
(with-vars [temp]
- (_.if (|> temp (_.= _.undefined) _.not)
- (_.return (..some temp))
- (_.return ..none))))
+ ($_ _.then
+ (_.define temp (_.at field object))
+ (_.if (_.= _.undefined temp)
+ (_.return ..none)
+ (_.return (..some temp))))))
(runtime: (js//set object field input)
($_ _.then
@@ -685,18 +686,46 @@
(_.delete (_.at field object))
(_.return object)))
-(runtime: (js//call object method inputs)
- (_.return (_.apply/2 (_.at method object) object inputs)))
-
(def: runtime//js
Statement
($_ _.then
@js//get
@js//set
@js//delete
- @js//call
))
+(runtime: (array//read idx array)
+ (let [fail! (_.return ..none)]
+ (_.if (_.< (_.the "length" array) idx)
+ (with-vars [temp]
+ ($_ _.then
+ (_.define temp (_.at idx array))
+ (_.if (_.= _.undefined temp)
+ fail!
+ (_.return (..some temp)))))
+ fail!)))
+
+(runtime: (array//write idx value array)
+ (_.if (_.< (_.the "length" array) idx)
+ ($_ _.then
+ (_.set (_.at idx array) value)
+ (_.return (..some array)))
+ (_.return ..none)))
+
+(runtime: (array//delete idx array)
+ (_.if (_.< (_.the "length" array) idx)
+ ($_ _.then
+ (_.delete (_.at idx array))
+ (_.return (..some array)))
+ (_.return ..none)))
+
+(def: runtime//array
+ Statement
+ ($_ _.then
+ @array//read
+ @array//write
+ @array//delete))
+
(def: runtime
Statement
($_ _.then
@@ -706,6 +735,7 @@
runtime//text
runtime//io
runtime//js
+ runtime//array
))
(def: #export artifact Text (format prefix ".js"))
diff --git a/stdlib/source/lux/tool/compiler/phase/translation/scheme/extension/common.jvm.lux b/stdlib/source/lux/tool/compiler/phase/translation/scheme/extension/common.jvm.lux
index 1c55abf83..d430aba24 100644
--- a/stdlib/source/lux/tool/compiler/phase/translation/scheme/extension/common.jvm.lux
+++ b/stdlib/source/lux/tool/compiler/phase/translation/scheme/extension/common.jvm.lux
@@ -15,16 +15,14 @@
["." macro (#+ with-gensyms)
["." code]
["s" syntax (#+ syntax:)]]
- [host (#+ import:)]]
+ [host (#+ import:)
+ ["_" scheme (#+ Expression Computation)]]]
[///
["." runtime (#+ Operation Phase Handler Bundle)]
["//." ///
["." synthesis (#+ Synthesis)]
["." extension
- ["." bundle]]
- [///
- [host
- ["_" scheme (#+ Expression Computation)]]]]])
+ ["." bundle]]]])
(syntax: (Vector {size s.nat} elemT)
(wrap (list (` [(~+ (list.repeat size elemT))]))))
diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux
index 7a76cd53b..c2ca8b3ba 100644
--- a/stdlib/source/test/lux.lux
+++ b/stdlib/source/test/lux.lux
@@ -5,7 +5,10 @@
[case (#+)]
[loop (#+)]
[function (#+)]
- [expression (#+)])]
+ [expression (#+)]
+ [extension (#+)
+ [common (#+)]
+ [host (#+)]])]
(.module:
[lux #*
[cli (#+ program:)]