From 4051a1cbe0999ee22bc395b059ea1556bcc002a0 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Wed, 1 Sep 2021 01:01:22 -0400 Subject: Updates to the JS compiler. --- documentation/bookmark/free.md | 1 + lux-bootstrapper/project.clj | 12 +- lux-js/commands.md | 8 +- lux-js/project.lux | 17 +++ lux-js/source/program.lux | 133 +++++++++++---------- stdlib/commands.md | 8 +- stdlib/project.lux | 3 + stdlib/source/documentation/lux/ffi.js.lux | 73 +++++++++++ .../source/documentation/lux/meta/annotation.lux | 5 +- stdlib/source/library/lux.lux | 48 ++------ stdlib/source/library/lux/ffi.js.lux | 51 +++----- stdlib/source/library/lux/ffi.jvm.lux | 2 +- stdlib/source/library/lux/meta/annotation.lux | 16 --- .../lux/phase/extension/generation/js/common.lux | 79 ++++++++++-- .../compiler/language/lux/phase/generation/js.lux | 47 ++------ .../language/lux/phase/generation/js/function.lux | 2 +- .../language/lux/phase/generation/js/structure.lux | 2 +- .../program/aedifex/dependency/resolution.lux | 25 ++-- stdlib/source/test/lux/meta/annotation.lux | 38 ------ 19 files changed, 297 insertions(+), 273 deletions(-) create mode 100644 lux-js/project.lux create mode 100644 stdlib/source/documentation/lux/ffi.js.lux diff --git a/documentation/bookmark/free.md b/documentation/bookmark/free.md index b33b2ac25..f2c7e864b 100644 --- a/documentation/bookmark/free.md +++ b/documentation/bookmark/free.md @@ -1,5 +1,6 @@ # Reference +1. https://free-for.dev/#/ 1. [Public APIs](https://github.com/public-apis/public-apis) 1. [](http://poly.pizza/) diff --git a/lux-bootstrapper/project.clj b/lux-bootstrapper/project.clj index f6c317476..55d62ac48 100644 --- a/lux-bootstrapper/project.clj +++ b/lux-bootstrapper/project.clj @@ -14,14 +14,14 @@ :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/core.match "0.2.1"] ;; Prefer when building Lua compiler. - [org.ow2.asm/asm-all "5.0.3"] + ;; [org.ow2.asm/asm-all "5.0.3"] ;; Prefer when building JS compiler. - ;; [org.ow2.asm/asm "7.3.1"] - ;; [org.ow2.asm/asm-commons "7.3.1"] - ;; [org.ow2.asm/asm-analysis "7.3.1"] - ;; [org.ow2.asm/asm-tree "7.3.1"] - ;; [org.ow2.asm/asm-util "7.3.1"] + [org.ow2.asm/asm "7.3.1"] + [org.ow2.asm/asm-commons "7.3.1"] + [org.ow2.asm/asm-analysis "7.3.1"] + [org.ow2.asm/asm-tree "7.3.1"] + [org.ow2.asm/asm-util "7.3.1"] ] :warn-on-reflection true :repositories [["snapshots" "https://oss.sonatype.org/content/repositories/snapshots/"] diff --git a/lux-js/commands.md b/lux-js/commands.md index b92d902ef..10029d6a2 100644 --- a/lux-js/commands.md +++ b/lux-js/commands.md @@ -8,8 +8,10 @@ cd ~/lux/lux-js/ && lein clean && lein lux auto test # Build ``` -cd ~/lux/lux-js/ && lein lux auto build -cd ~/lux/lux-js/ && lein clean && lein lux auto build +## Develop +cd ~/lux/lux-js/ \ +&& lein clean \ +&& lein lux auto build ## Build JVM-based compiler cd ~/lux/lux-js/ \ @@ -20,7 +22,7 @@ cd ~/lux/lux-js/ \ ## Use JVM-based compiler to produce a JS/Node-based compiler. cd ~/lux/lux-js/ \ && lein clean \ -&& java -jar jvm_based_compiler.jar build --source ~/lux/lux-js/source --target ~/lux/lux-js/target --module program \ +&& time java -jar jvm_based_compiler.jar build --source ~/lux/lux-js/source --target ~/lux/lux-js/target --module program \ && mv target/program.js node_based_compiler.js ## Use JS/Node-based compiler to produce another JS/Node-based compiler. diff --git a/lux-js/project.lux b/lux-js/project.lux new file mode 100644 index 000000000..2163ba34c --- /dev/null +++ b/lux-js/project.lux @@ -0,0 +1,17 @@ +{"" + {#identity ["com.github.luxlang" "lux-js" "0.6.0-SNAPSHOT"] + #description "A JavaScript compiler for Lux." + + #deploy_repositories {"snapshots" "https://oss.sonatype.org/content/repositories/snapshots/" + "releases" "https://oss.sonatype.org/service/local/staging/deploy/maven2/"} + + #repositories ["https://oss.sonatype.org/content/repositories/snapshots/" + "https://oss.sonatype.org/service/local/staging/deploy/maven2/"] + + #dependencies [["com.github.luxlang" "stdlib" "0.6.0-SNAPSHOT" "tar"]] + + #program "program"} + + "jvm" + {#compiler ["com.github.luxlang" "lux-jvm" "0.6.0-SNAPSHOT" "jar"] + #dependencies [["org.openjdk.nashorn" "nashorn-core" "15.1" "jar"]]}} diff --git a/lux-js/source/program.lux b/lux-js/source/program.lux index 29cc0a8ab..ea9011dac 100644 --- a/lux-js/source/program.lux +++ b/lux-js/source/program.lux @@ -129,7 +129,8 @@ (import: org/openjdk/nashorn/api/scripting/ScriptObjectMirror ["#::." (size [] int) - (toString [] java/lang/String)]) + (toString [] java/lang/String) + (getOwnKeys [boolean] [java/lang/String])]) (import: org/openjdk/nashorn/internal/runtime/Undefined) @@ -173,7 +174,7 @@ (|> value .nat runtime.low jvm_int) _ - (panic! (exception.construct ..unknown_member [member (:as java/lang/Object value)])))) + (panic! (exception.error ..unknown_member [member (:as java/lang/Object value)])))) )) (def: (::toString js_object) @@ -256,7 +257,7 @@ (|> value (array.read! 2) maybe.trusted js_object (:as java/lang/Object)) _ - (panic! (exception.construct ..unknown_member [(:as Text member) (:as java/lang/Object value)]))) + (panic! (exception.error ..unknown_member [(:as Text member) (:as java/lang/Object value)]))) ) (org/openjdk/nashorn/api/scripting/AbstractJSObject [] (getSlot self {idx int}) java/lang/Object @@ -272,7 +273,17 @@ (exception: (unknown_kind_of_host_object {object java/lang/Object}) (exception.report ["Class" (java/lang/Object::toString (java/lang/Object::getClass object))] - ["Object" (java/lang/Object::toString object)])) + ["Object" (java/lang/Object::toString object)] + ["Keys" (case (ffi.check org/openjdk/nashorn/api/scripting/ScriptObjectMirror object) + (#.Some object) + (|> object + (org/openjdk/nashorn/api/scripting/ScriptObjectMirror::getOwnKeys true) + (:as (Array Text)) + (array.list #.None) + (%.list %.text)) + + #.None + "???")])) (def: (check_int js_object) (-> org/openjdk/nashorn/api/scripting/ScriptObjectMirror @@ -286,9 +297,9 @@ {[(java/lang/Number::longValue high) (java/lang/Number::longValue low)] [high low]}) - (#.Some (.int (n.+ (|> high .nat (i64.left_shift 32)) + (#.Some (.int (n.+ (|> high .nat (i64.left_shifted 32)) (if (i.< +0 (.int low)) - (|> low .nat (i64.left_shift 32) (i64.right_shift 32)) + (|> low .nat (i64.left_shifted 32) (i64.right_shifted 32)) (.nat low))))) _ @@ -305,15 +316,15 @@ {(ffi.check java/lang/Number tag) (#.Some tag)} {(lux_object value) - (#.Some value)}) - (#.Some [(java/lang/Number::intValue tag) - (maybe.default (ffi.null) ?flag) + (#try.Success value)}) + (#.Some [(java/lang/Number::intValue (:as java/lang/Number tag)) + (maybe.else (ffi.null) ?flag) value]) _ #.None)) - (def: (check_array lux_object js_object) + (def: (check_tuple lux_object js_object) (-> (-> java/lang/Object (Try Any)) org/openjdk/nashorn/api/scripting/ScriptObjectMirror (Maybe (Array java/lang/Object))) @@ -321,7 +332,7 @@ (let [num_keys (.nat (org/openjdk/nashorn/api/scripting/ScriptObjectMirror::size js_object))] (loop [idx 0 output (: (Array java/lang/Object) - (array.new num_keys))] + (array.empty num_keys))] (if (n.< num_keys idx) (case (org/openjdk/nashorn/api/scripting/JSObject::getMember (%.nat idx) js_object) (#.Some member) @@ -345,22 +356,22 @@ (def: (lux_object js_object) (-> java/lang/Object (Try Any)) (`` (<| (if (ffi.null? js_object) - (exception.throw ..null_has_no_lux_representation [#.None])) + (exception.except ..null_has_no_lux_representation [#.None])) (case (ffi.check org/openjdk/nashorn/internal/runtime/Undefined js_object) (#.Some _) - (exception.throw ..undefined_has_no_lux_representation []) + (exception.except ..undefined_has_no_lux_representation []) #.None) (~~ (template [] [(case (ffi.check js_object) (#.Some js_object) - (exception.return js_object) + (#try.Success js_object) #.None)] [java/lang/Boolean] [java/lang/String])) (~~ (template [ ] [(case (ffi.check js_object) (#.Some js_object) - (exception.return ( js_object)) + (#try.Success ( js_object)) #.None)] [java/lang/Number java/lang/Number::doubleValue] @@ -370,26 +381,28 @@ (#.Some js_object) (case (check_int js_object) (#.Some value) - (exception.return value) + (#try.Success value) #.None (case (check_variant lux_object js_object) (#.Some value) - (exception.return value) + (#try.Success value) #.None - (case (check_array lux_object js_object) + (case (check_tuple lux_object js_object) (#.Some value) - (exception.return value) + (#try.Success value) #.None (if (org/openjdk/nashorn/api/scripting/JSObject::isFunction js_object) - (exception.return js_object) - ... (exception.throw ..unknown_kind_of_host_object (:as java/lang/Object js_object)) - (exception.return js_object))))) + (#try.Success js_object) + ... (exception.except ..unknown_kind_of_host_object [(:as java/lang/Object js_object)]) + (#try.Success js_object) + )))) #.None) ... else - (exception.throw ..unknown_kind_of_host_object (:as java/lang/Object js_object)) + ... (exception.except ..unknown_kind_of_host_object [(:as java/lang/Object js_object)]) + (#try.Success js_object) ))) (def: (ensure_function function) @@ -413,7 +426,7 @@ (|>> (:as (Array java/lang/Object)) js_structure (:as java/lang/Object)))] (<| (:as (Try (Try [Lux (List Code)]))) (org/openjdk/nashorn/api/scripting/JSObject::call #.None - (|> (array.new 2) + (|> (array.empty 2) (: (Array java/lang/Object)) (array.write! 0 (to_js inputs)) (array.write! 1 (to_js lux))) @@ -438,7 +451,7 @@ (#try.Failure error)) #.None - (exception.throw ..cannot_apply_a_non_function (:as java/lang/Object macro)))) + (exception.except ..cannot_apply_a_non_function (:as java/lang/Object macro)))) ) @.js @@ -457,24 +470,24 @@ (..lux_object output) #.None - (exception.throw ..null_has_no_lux_representation [(#.Some input)])))) + (exception.except ..null_has_no_lux_representation [(#.Some input)])))) (def: (execute! interpreter input) (-> javax/script/ScriptEngine _.Statement (Try Any)) (do try.monad [?output (javax/script/ScriptEngine::eval (_.code input) interpreter)] - (wrap []))) + (in []))) (def: (define! interpreter context custom input) (-> javax/script/ScriptEngine Context (Maybe Text) _.Expression (Try [Text Any _.Statement])) - (let [global (maybe.default (reference.artifact context) - custom) + (let [global (maybe.else (reference.artifact context) + custom) @global (_.var global)] (do try.monad - [#let [definition (_.define @global input)] + [.let [definition (_.define @global input)] _ (execute! interpreter definition) value (evaluate! interpreter context @global)] - (wrap [global value definition])))) + (in [global value definition])))) (def: host (IO (Host _.Expression _.Statement)) @@ -515,27 +528,27 @@ [?output (..eval (_.code input))] (case ?output (#.Some output) - (wrap output) + (in output) #.None - (exception.throw ..null_has_no_lux_representation [(#.Some input)])))) + (exception.except ..null_has_no_lux_representation [(#.Some input)])))) (def: (execute! input) (-> _.Statement (Try Any)) (do try.monad [?output (..eval (_.code input))] - (wrap []))) + (in []))) (def: (define! context custom input) (-> Context (Maybe Text) _.Expression (Try [Text Any _.Statement])) - (let [global (maybe.default (reference.artifact context) - custom) + (let [global (maybe.else (reference.artifact context) + custom) @global (_.var global)] (do try.monad - [#let [definition (_.define @global input)] + [.let [definition (_.define @global input)] _ (..execute! definition) value (..evaluate! context @global)] - (wrap [global value definition])))) + (in [global value definition])))) (def: host (IO (Host _.Expression _.Statement)) @@ -558,30 +571,30 @@ )}) (def: (phase_wrapper archive) - (-> Archive (runtime.Operation platform.Phase_Wrapper)) + (-> Archive (runtime.Operation phase.Wrapper)) (do phase.monad [] - (wrap (:as platform.Phase_Wrapper - (for {... The implementation for @.old is technically incorrect. - ... However, the JS compiler runs fast enough on Node to be fully hosted there. - ... And running the JS compiler on the JVM (on top of Nashorn) is impractically slow. - ... This means that in practice, only the @.js implementation matters. - ... And since no cross-language boundary needs to be handled, it's a correct implementation. - @.old (|>>) - @.js (|>>)}))))) + (in (:as phase.Wrapper + (for {... The implementation for @.old is technically incorrect. + ... However, the JS compiler runs fast enough on Node to be fully hosted there. + ... And running the JS compiler on the JVM (on top of Nashorn) is impractically slow. + ... This means that in practice, only the @.js implementation matters. + ... And since no cross-language boundary needs to be handled, it's a correct implementation. + @.old (|>>) + @.js (|>>)}))))) (def: platform (IO (Platform [Register Text] _.Expression _.Statement)) (do io.monad [host ..host] - (wrap {#platform.&file_system (for {@.old (file.async file.default) - @.jvm (file.async file.default) - @.js file.default}) - #platform.host host - #platform.phase js.generate - #platform.runtime runtime.generate - #platform.phase_wrapper ..phase_wrapper - #platform.write (|>> _.code (\ utf8.codec encoded))}))) + (in {#platform.&file_system (for {@.old (file.async file.default) + @.jvm (file.async file.default) + @.js file.default}) + #platform.host host + #platform.phase js.generate + #platform.runtime runtime.generate + #platform.phase_wrapper ..phase_wrapper + #platform.write (|>> _.code (\ utf8.codec encoded))}))) (def: (program context program) (Program _.Expression _.Statement) @@ -602,7 +615,7 @@ (for {@.old (def: (extender phase_wrapper) - (-> platform.Phase_Wrapper Extender) + (-> phase.Wrapper Extender) ... TODO: Stop relying on coercions ASAP. (<| (:as Extender) (function (@self handler)) @@ -617,10 +630,10 @@ (:as Try) (do try.monad [handler (try.of_maybe (..ensure_function handler)) - #let [to_js (: (-> Any java/lang/Object) + .let [to_js (: (-> Any java/lang/Object) (|>> (:as (Array java/lang/Object)) js_structure (:as java/lang/Object)))] output (org/openjdk/nashorn/api/scripting/JSObject::call #.None - (|> (array.new 5) + (|> (array.empty 5) (: (Array java/lang/Object)) (array.write! 0 name) (array.write! 1 (:as java/lang/Object (extender phase))) @@ -632,7 +645,7 @@ @.js (def: (extender phase_wrapper handler) - (-> platform.Phase_Wrapper Extender) + (-> phase.Wrapper Extender) (:expected handler))}) (def: (declare_success! _) @@ -657,7 +670,7 @@ generation.bundle (function.constant extension/bundle.empty) ..program - [(& Register Text) _.Expression _.Statement] + [(And Register Text) _.Expression _.Statement] ..extender service [(packager.package _.use_strict _.code _.then ..scope) diff --git a/stdlib/commands.md b/stdlib/commands.md index adc090c4d..dc74aa294 100644 --- a/stdlib/commands.md +++ b/stdlib/commands.md @@ -11,6 +11,10 @@ cd ~/lux/stdlib/ \ && lux clean \ && lux with jvm with bibliotheca auto test +cd ~/lux/stdlib/ \ +&& lux clean \ +&& lux with js with bibliotheca auto test + cd ~/lux/stdlib/ \ && lux clean \ && lux with python with bibliotheca auto test @@ -69,11 +73,11 @@ cd ~/lux/stdlib/ \ ``` cd ~/lux/stdlib/ \ && lux clean \ -&& lux with aedifex auto build +&& lux with jvm with aedifex auto build cd ~/lux/stdlib/ \ && lux clean \ -&& lux with aedifex build \ +&& lux with jvm with aedifex build \ && mv target/program.jar aedifex.jar ``` diff --git a/stdlib/project.lux b/stdlib/project.lux index 26ea4061b..5e1b4d02a 100644 --- a/stdlib/project.lux +++ b/stdlib/project.lux @@ -10,6 +10,9 @@ "jvm" {#compiler ["com.github.luxlang" "lux-jvm" "0.6.0-SNAPSHOT" "jar"]} + "js" + {#compiler ["com.github.luxlang" "lux-js" "0.6.0-SNAPSHOT" "js"]} + "python" {#compiler ["com.github.luxlang" "lux-python" "0.6.0-SNAPSHOT" "jar"]} diff --git a/stdlib/source/documentation/lux/ffi.js.lux b/stdlib/source/documentation/lux/ffi.js.lux new file mode 100644 index 000000000..72ee6ef34 --- /dev/null +++ b/stdlib/source/documentation/lux/ffi.js.lux @@ -0,0 +1,73 @@ +(.module: + [library + [lux (#- int char type :as) + ["$" documentation (#+ documentation:)] + [data + ["." text (#+ \n) + ["%" format (#+ format)]]] + [macro + ["." template]]]] + [\\library + ["." /]]) + +(documentation: /.null + "The null pointer.") + +(documentation: /.import: + "Easily import types, methods, functions and constants." + [(import: Uint8Array) + + (import: TextEncoder + ["#::." + (new [/.String]) + (encode [/.String] Uint8Array)]) + + (import: TextDecoder + ["#::." + (new [/.String]) + (decode [/.String] String)])]) + +(documentation: /.type_of + "The type of an object, as text." + [(= "boolean" + (type_of #1))] + [(= "number" + (type_of +123.456))] + [(= "string" + (type_of "789"))] + [(= "function" + (type_of (function (_ value) value)))]) + +(documentation: /.constant + "Allows using definitions from the JavaScript host platform." + [(constant .Frac [Math PI])]) + +(documentation: /.closure + (format "Allows defining closures/anonymous-functions in the form that JavaScript expects." + \n "This is useful for adapting Lux functions for usage by JavaScript code.") + [(: /.Function + (closure [left right] + (do_something (:as Foo left) (:as Bar right))))]) + +(.def: .public documentation + (.List $.Module) + ($.module /._ + "" + [..null + ..import: + ..type_of + ..constant + ..closure + ($.default (/.Object brand)) + ($.default /.Function) + ($.default /.Symbol) + ($.default /.Null) + ($.default /.Undefined) + ($.default /.Boolean) + ($.default /.Number) + ($.default /.String) + ($.default /.null?) + ($.default /.on_browser?) + ($.default /.on_nashorn?) + ($.default /.on_node_js?)] + [])) diff --git a/stdlib/source/documentation/lux/meta/annotation.lux b/stdlib/source/documentation/lux/meta/annotation.lux index c46961d3a..2ddb4826a 100644 --- a/stdlib/source/documentation/lux/meta/annotation.lux +++ b/stdlib/source/documentation/lux/meta/annotation.lux @@ -46,9 +46,6 @@ ..tuple ..record ($.default /.Annotation) - ($.default /.documentation) ($.default /.flagged?) - ($.default /.implementation?) - ($.default /.function_arguments) - ($.default /.type_arguments)] + ($.default /.implementation?)] [])) diff --git a/stdlib/source/library/lux.lux b/stdlib/source/library/lux.lux index 804c27ee5..d717434be 100644 --- a/stdlib/source/library/lux.lux +++ b/stdlib/source/library/lux.lux @@ -50,9 +50,7 @@ (2 #0 (4 #0 1) (9 #0 (4 #0 1) (4 #0 0)))))) [dummy_location - (9 #1 (0 #1 [[dummy_location (7 #0 ["library/lux" "type_args"])] - [dummy_location (9 #0 (0 #1 [dummy_location (5 #0 "a")] (0 #0)))]] - (0 #0)))] + (9 #1 (0 #0))] ("End" "Item") #1) @@ -132,9 +130,7 @@ ... "lux.Some" (4 #0 1)))) [dummy_location - (9 #1 (#Item [[dummy_location (7 #0 ["library/lux" "type_args"])] - [dummy_location (9 #0 (#Item [dummy_location (5 #0 "a")] #End))]] - #End))] + (9 #1 #End)] ("None" "Some") #1) @@ -221,9 +217,7 @@ (#Product (#Parameter 3) (#Parameter 1))))) [dummy_location - (9 #1 (#Item [[dummy_location (7 #0 ["library/lux" "type_args"])] - [dummy_location (9 #0 (#Item [dummy_location (5 #0 "m")] (#Item [dummy_location (5 #0 "v")] #End)))]] - #End))] + (9 #1 #End)] ["meta" "datum"] #1) @@ -273,9 +267,7 @@ (#Parameter 0)) (#Parameter 1))))) [dummy_location - (9 #1 (#Item [[dummy_location (7 #0 ["library/lux" "type_args"])] - [dummy_location (9 #0 (#Item [dummy_location (5 #0 "w")] #End))]] - #End))] + (9 #1 #End)] ("Bit" "Nat" "Int" "Rev" "Frac" "Text" "Identifier" "Tag" "Form" "Tuple" "Record") #1) @@ -462,9 +454,7 @@ (#Apply (#Product (#Parameter 3) (#Parameter 1)) List))))) - (record$ (#Item [(tag$ ["library/lux" "type_args"]) - (tuple$ (#Item (text$ "k") (#Item (text$ "v") #End)))] - #End)) + (record$ #End) ["counter" "mappings"] .public) @@ -517,9 +507,7 @@ (#Parameter 3) ... "lux.Right" (#Parameter 1))))) - (record$ (#Item [(tag$ ["library/lux" "type_args"]) - (tuple$ (#Item (text$ "l") (#Item (text$ "r") #End)))] - #End)) + (record$ #End) ("Left" "Right") .public) @@ -707,9 +695,7 @@ (#Function Lux (#Apply (#Product Lux (#Parameter 1)) (#Apply Text Either)))))) - (record$ (#Item [(tag$ ["library/lux" "type_args"]) - (tuple$ (#Item (text$ "a") #End))] - #End)) + (record$ #End) .public) ... (type: .public Macro' @@ -2794,24 +2780,6 @@ (~ (definition_annotation_value v))]))) kvs))) -(def:' .private (with_function_parameters parameters meta) - (-> (List Code) Code Code) - (case parameters - #End - meta - - _ - (` (#.Item [[(~ location_code) (#.Tag ["library/lux" "func_args"])] - [(~ location_code) (#.Tuple (.list (~+ (list\each (function (_ parameter) - (` [(~ location_code) (#.Text (~ (text$ (code\encoded parameter))))])) - parameters))))]] - (~ meta))))) - -(def:' .private (with_type_args args) - (-> (List Code) Code) - (` {#.type_args [(~+ (list\each (function (_ arg) (text$ (code\encoded arg))) - args))]})) - (def:' .private (endP tokens) (-> (List Code) (Maybe Any)) (case tokens @@ -2998,7 +2966,7 @@ (in_meta (list (` ("lux def" (~ (..local_identifier$ name)) (~ body) [(~ location_code) - (#.Record (~ (with_function_parameters parameters =annotations)))] + (#.Record (~ =annotations))] (~ export_policy)))))) #None diff --git a/stdlib/source/library/lux/ffi.js.lux b/stdlib/source/library/lux/ffi.js.lux index 247894177..6a130d4a1 100644 --- a/stdlib/source/library/lux/ffi.js.lux +++ b/stdlib/source/library/lux/ffi.js.lux @@ -23,11 +23,15 @@ ["." template]]]]) (abstract: .public (Object brand) + {} + Any) (template [] [(with_expansions [ (template.identifier [ "'"])] (abstract: + {} + Any (type: .public @@ -153,7 +157,6 @@ input)) (def: .public (null _) - {#.doc (example "The null pointer.")} (-> Any Nothing) (:expected ("js object null"))) @@ -238,18 +241,6 @@ (~+ (list\each (with_null g!temp) g!inputs))))))))))) (syntax: .public (import: [import ..import]) - {#.doc (example "Easily import types, methods, functions and constants." - (import: Uint8Array) - - (import: TextEncoder - ["#::." - (new [..String]) - (encode [..String] Uint8Array)]) - - (import: TextDecoder - ["#::." - (new [..String]) - (decode [..String] String)]))} (with_identifiers [g!temp g!_] (case import (#Class [[class_name class_parameters] format members]) @@ -337,17 +328,10 @@ ))) (template: .public (type_of object) - {#.doc (example "The type of an object, as text." - (and (= "boolean" (type_of #1)) - (= "number" (type_of +123.456)) - (= "string" (type_of "789")) - (= "function" (type_of (function (_ value) value)))))} - ("js type-of" object)) + [("js type-of" object)]) (syntax: .public (constant [type .any [head tail] (.tuple (<>.and .local_identifier (<>.some .local_identifier)))]) - {#.doc (example "Allows using definitions from the JavaScript host platform." - (constant .Frac [Math PI]))} (with_identifiers [g!_] (let [constant (` ("js constant" (~ (code.text head))))] (case tail @@ -372,12 +356,12 @@ (~+ (list\each code.local_identifier tail))]))))))))))) (template: (!defined? ) - (.case (..constant Any ) - #.None - .false + [(.case (..constant Any ) + #.None + .false - (#.Some _) - .true)) + (#.Some _) + .true)]) (template [ ] [(def: .public @@ -404,13 +388,8 @@ false)) (template: .public (closure ) - {#.doc (example "Allows defining closures/anonymous-functions in the form that JavaScript expects." - "This is useful for adapting Lux functions for usage by JavaScript code." - (: ..Function - (closure [left right] - (do_something (:as Foo left) (:as Bar right)))))} - (.:as ..Function - (`` ("js function" - (~~ (template.amount )) - (.function (_ []) - ))))) + [(.:as ..Function + (`` ("js function" + (~~ (template.amount )) + (.function (_ []) + ))))]) diff --git a/stdlib/source/library/lux/ffi.jvm.lux b/stdlib/source/library/lux/ffi.jvm.lux index e50f12602..412f5c0d6 100644 --- a/stdlib/source/library/lux/ffi.jvm.lux +++ b/stdlib/source/library/lux/ffi.jvm.lux @@ -932,7 +932,7 @@ (def: (import_member_args^ type_vars) (-> (List (Type Var)) (Parser (List [Bit (Type Value)]))) - (.tuple (<>.some (<>.and (<>.parses? (.tag! ["" "?"])) + (.tuple (<>.some (<>.and (<>.parses? (.this! (' "?"))) (..type^ type_vars))))) (def: import_member_return_flags^ diff --git a/stdlib/source/library/lux/meta/annotation.lux b/stdlib/source/library/lux/meta/annotation.lux index d2cc9a45a..5617cd88c 100644 --- a/stdlib/source/library/lux/meta/annotation.lux +++ b/stdlib/source/library/lux/meta/annotation.lux @@ -56,10 +56,6 @@ [record #.Record (List [Code Code])] ) -(def: .public documentation - (-> Annotation (Maybe Text)) - (..text (name_of #.doc))) - (def: .public (flagged? flag) (-> Name Annotation Bit) (|>> (..bit flag) (maybe.else false))) @@ -76,15 +72,3 @@ _ #.None)) - -(template [ ] - [(def: .public ( ann) - (-> Annotation (List Text)) - (<| (maybe.else (list)) - (do {! maybe.monad} - [args (..tuple (name_of ) ann)] - (monad.each ! ..text_parser args))))] - - [function_arguments #.func_args] - [type_arguments #.type_args] - ) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/js/common.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/js/common.lux index 3aad68a7f..be57d4c55 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/js/common.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/generation/js/common.lux @@ -25,12 +25,18 @@ [extension (#+ Nullary Unary Binary Trinary nullary unary binary trinary)] ["//" js #_ - ["#." runtime (#+ Operation Phase Handler Bundle Generator)] - ["#." primitive]]] + ["#." runtime (#+ Operation Phase Phase! Handler Bundle Generator)] + ["#." primitive] + ["#." structure] + ["#." reference] + ["#." case] + ["#." loop] + ["#." function]]] [// - [synthesis (#+ %synthesis)] + [analysis (#+)] + ["." synthesis (#+ %synthesis)] [/// - ["#" phase]]]]]) + ["#" phase ("#\." monad)]]]]]) (def: .public (custom [parser handler]) (All (_ s) @@ -91,6 +97,48 @@ (//runtime.io//log messageG) //runtime.unit)) +(def: .public (statement expression archive synthesis) + Phase! + (case synthesis + ... TODO: Get rid of this ASAP + (#synthesis.Extension "lux syntax char case!" parameters) + (do /////.monad + [body (expression archive synthesis)] + (in (:as Statement body))) + + (^template [] + [(^ ( value)) + (/////\each _.return (expression archive synthesis))]) + ([synthesis.bit] + [synthesis.i64] + [synthesis.f64] + [synthesis.text] + [synthesis.variant] + [synthesis.tuple] + [#synthesis.Reference] + [synthesis.branch/get] + [synthesis.function/apply] + [#synthesis.Extension]) + + (^ (synthesis.branch/case case)) + (//case.case! statement expression archive case) + + (^ (synthesis.branch/let let)) + (//case.let! statement expression archive let) + + (^ (synthesis.branch/if if)) + (//case.if! statement expression archive if) + + (^ (synthesis.loop/scope scope)) + (//loop.scope! statement expression archive scope) + + (^ (synthesis.loop/recur updates)) + (//loop.recur! statement expression archive updates) + + (^ (synthesis.function/abstraction abstraction)) + (/////\each _.return (//function.function statement expression archive abstraction)) + )) + ... TODO: Get rid of this ASAP (def: lux::syntax_char_case! (..custom [($_ <>.and @@ -102,20 +150,25 @@ (function (_ extension_name phase archive [input else conditionals]) (do {! /////.monad} [inputG (phase archive input) - elseG (phase archive else) - conditionalsG (: (Operation (List [(List Literal) + else! (..statement phase archive else) + conditionals! (: (Operation (List [(List Literal) Statement])) (monad.each ! (function (_ [chars branch]) (do ! - [branchG (phase archive branch)] + [branch! (..statement phase archive branch)] (in [(list\each (|>> .int _.int) chars) - (_.return branchG)]))) + branch!]))) conditionals))] - (in (_.apply/* (_.closure (list) - (_.switch (_.the //runtime.i64_low_field inputG) - conditionalsG - (#.Some (_.return elseG)))) - (list)))))])) + ... (in (_.apply/* (_.closure (list) + ... (_.switch (_.the //runtime.i64_low_field inputG) + ... conditionals! + ... (#.Some (_.return else!)))) + ... (list))) + (in (<| (:as Expression) + (: Statement) + (_.switch (_.the //runtime.i64_low_field inputG) + conditionals! + (#.Some else!))))))])) ... [Bundles] (def: lux_procs diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js.lux index 61119e473..c240161ee 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js.lux @@ -18,7 +18,10 @@ ["/#" // #_ ["#." reference] ["/#" // #_ - ["#." extension] + ["#." extension + [generation + [js + ["#/." common]]]] ["/#" // #_ [analysis (#+)] ["." synthesis] @@ -27,42 +30,6 @@ [reference (#+) [variable (#+)]]]]]]]) -(def: (statement expression archive synthesis) - Phase! - (case synthesis - (^template [] - [(^ ( value)) - (//////phase\each _.return (expression archive synthesis))]) - ([synthesis.bit] - [synthesis.i64] - [synthesis.f64] - [synthesis.text] - [synthesis.variant] - [synthesis.tuple] - [#synthesis.Reference] - [synthesis.branch/get] - [synthesis.function/apply] - [#synthesis.Extension]) - - (^ (synthesis.branch/case case)) - (/case.case! statement expression archive case) - - (^ (synthesis.branch/let let)) - (/case.let! statement expression archive let) - - (^ (synthesis.branch/if if)) - (/case.if! statement expression archive if) - - (^ (synthesis.loop/scope scope)) - (/loop.scope! statement expression archive scope) - - (^ (synthesis.loop/recur updates)) - (/loop.recur! statement expression archive updates) - - (^ (synthesis.function/abstraction abstraction)) - (//////phase\each _.return (/function.function statement expression archive abstraction)) - )) - (exception: .public cannot_recur_as_an_expression) (def: (expression archive synthesis) @@ -86,7 +53,7 @@ (//reference.reference /reference.system archive value) (^ (synthesis.branch/case case)) - (/case.case ..statement expression archive case) + (/case.case ///extension/common.statement expression archive case) (^ (synthesis.branch/let let)) (/case.let expression archive let) @@ -98,13 +65,13 @@ (/case.get expression archive get) (^ (synthesis.loop/scope scope)) - (/loop.scope ..statement expression archive scope) + (/loop.scope ///extension/common.statement expression archive scope) (^ (synthesis.loop/recur updates)) (//////phase.except ..cannot_recur_as_an_expression []) (^ (synthesis.function/abstraction abstraction)) - (/function.function ..statement expression archive abstraction) + (/function.function ///extension/common.statement expression archive abstraction) (^ (synthesis.function/apply application)) (/function.apply expression archive application) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/function.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/function.lux index 078cc797d..11a0b5640 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/function.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/function.lux @@ -1,6 +1,6 @@ (.module: [library - [lux (#- function) + [lux (#- Variant Tuple function) [abstract ["." monad (#+ do)]] [data diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/structure.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/structure.lux index 3788b7f6d..8b91f6d95 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/structure.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/js/structure.lux @@ -1,6 +1,6 @@ (.module: [library - [lux #* + [lux (#- Variant Tuple) [abstract ["." monad (#+ do)]] [target diff --git a/stdlib/source/program/aedifex/dependency/resolution.lux b/stdlib/source/program/aedifex/dependency/resolution.lux index a90712796..23a572506 100644 --- a/stdlib/source/program/aedifex/dependency/resolution.lux +++ b/stdlib/source/program/aedifex/dependency/resolution.lux @@ -7,7 +7,8 @@ [abstract [codec (#+ Codec)] [equivalence (#+ Equivalence)] - [monad (#+ do)]] + [monad (#+ do)] + ["." predicate (#+ Predicate)]] [control ["." maybe] ["." try (#+ Try) ("#\." functor)] @@ -232,9 +233,13 @@ (case ?package (#try.Success package) (do ! - [.let [sub_dependencies (|> package + [.let [redundant? (: (Predicate Dependency) + (predicate.or (\ //.equivalence = head) + (dictionary.key? resolution))) + sub_dependencies (|> package ///package.dependencies - (try\each set.list) + (try\each (|>> set.list + (list.only (|>> redundant? not)))) (try.else (list))) ... For security reasons, it's not a good idea to allow dependencies to introduce repositories. ... package_repositories (|> package @@ -243,17 +248,13 @@ ... (try.else (list)) ... (list\each new_repository)) ... sub_repositories (list\composite repositories package_repositories) - sub_repositories repositories] - [successes failures resolution] (recur sub_repositories - (#.Item head successes) - failures - sub_dependencies - (dictionary.has head package resolution))] + ]] (recur repositories - successes + (#.Item head successes) failures - tail - resolution)) + (set.list (set.union (set.of_list //.hash tail) + (set.of_list //.hash sub_dependencies))) + (dictionary.has head package resolution))) (#try.Failure error) (recur repositories diff --git a/stdlib/source/test/lux/meta/annotation.lux b/stdlib/source/test/lux/meta/annotation.lux index 772a403ad..a610d66eb 100644 --- a/stdlib/source/test/lux/meta/annotation.lux +++ b/stdlib/source/test/lux/meta/annotation.lux @@ -113,29 +113,6 @@ /.implementation?))))) )))) -(def: arguments - Test - (do {! random.monad} - [key ..random_key] - (`` ($_ _.and - (~~ (template [ ] - [(do ! - [expected (random.list 5 (random.ascii/alpha 1))] - (_.cover [] - (and (|> expected (list\each code.text) code.tuple - (..annotation (name_of )) - - (\ (list.equivalence text.equivalence) = expected)) - (|> expected (list\each code.text) code.tuple - (..annotation key) - - (\ (list.equivalence text.equivalence) = (list))))))] - - [/.function_arguments #.func_args] - [/.type_arguments #.type_args] - )) - )))) - (def: .public test Test (<| (_.covering /._) @@ -153,21 +130,6 @@ (code\= expected actual)))))) ..typed_value - - (do ! - [expected (random.ascii/alpha 10)] - (_.cover [/.documentation] - (and (not (|> expected code.text - (..annotation key) - /.documentation - (!expect (^multi (#.Some actual) - (\ text.equivalence = expected actual))))) - (|> expected code.text - (..annotation (name_of #.doc)) - /.documentation - (!expect (^multi (#.Some actual) - (\ text.equivalence = expected actual))))))) ..flag - ..arguments )))) -- cgit v1.2.3