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. --- 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 ----------- 14 files changed, 195 insertions(+), 204 deletions(-) create mode 100644 stdlib/source/documentation/lux/ffi.js.lux (limited to 'stdlib') 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