diff options
author | Eduardo Julian | 2021-03-01 01:49:30 -0400 |
---|---|---|
committer | Eduardo Julian | 2021-03-01 01:49:30 -0400 |
commit | cbc41f10fb3e0e776767d2266b22068172b0f69a (patch) | |
tree | 0344edcbe40edf51d16eb70b12a72e97e3c37f11 /stdlib/source/lux/tool | |
parent | 69edb6de2ecf62881bcde1b8013c98450a6a52bc (diff) |
Done with Ruby.
Diffstat (limited to 'stdlib/source/lux/tool')
13 files changed, 704 insertions, 245 deletions
diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux index 04df1bdbb..99154e105 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux @@ -28,8 +28,7 @@ ["." phase]]]]]]) (def: Nil - (for {@.lua - host.Nil} + (for {@.lua host.Nil} Any)) (def: Object @@ -222,7 +221,7 @@ [_ (analysis/type.infer ..Object)] (wrap (#analysis.Extension extension (list (analysis.text name))))))])) -(def: python::function +(def: lua::function Handler (custom [($_ <>.and <c>.nat <c>.any) @@ -247,6 +246,6 @@ (bundle.install "apply" lua::apply) (bundle.install "power" lua::power) (bundle.install "import" lua::import) - (bundle.install "function" python::function) + (bundle.install "function" lua::function) (bundle.install "script universe" (/.nullary .Bit)) ))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux index 3b9f4ad75..8bbd32b3c 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/analysis/ruby.lux @@ -27,8 +27,172 @@ [/// ["." phase]]]]]]) +(def: array::new + Handler + (custom + [<c>.any + (function (_ extension phase archive lengthC) + (do phase.monad + [lengthA (analysis/type.with_type Nat + (phase archive lengthC)) + [var_id varT] (analysis/type.with_env check.var) + _ (analysis/type.infer (type (Array varT)))] + (wrap (#analysis.Extension extension (list lengthA)))))])) + +(def: array::length + Handler + (custom + [<c>.any + (function (_ extension phase archive arrayC) + (do phase.monad + [[var_id varT] (analysis/type.with_env check.var) + arrayA (analysis/type.with_type (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.infer Nat)] + (wrap (#analysis.Extension extension (list arrayA)))))])) + +(def: array::read + Handler + (custom + [(<>.and <c>.any <c>.any) + (function (_ extension phase archive [indexC arrayC]) + (do phase.monad + [indexA (analysis/type.with_type Nat + (phase archive indexC)) + [var_id varT] (analysis/type.with_env check.var) + arrayA (analysis/type.with_type (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.infer varT)] + (wrap (#analysis.Extension extension (list indexA arrayA)))))])) + +(def: array::write + Handler + (custom + [($_ <>.and <c>.any <c>.any <c>.any) + (function (_ extension phase archive [indexC valueC arrayC]) + (do phase.monad + [indexA (analysis/type.with_type Nat + (phase archive indexC)) + [var_id varT] (analysis/type.with_env check.var) + valueA (analysis/type.with_type varT + (phase archive valueC)) + arrayA (analysis/type.with_type (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.infer (type (Array varT)))] + (wrap (#analysis.Extension extension (list indexA valueA arrayA)))))])) + +(def: array::delete + Handler + (custom + [($_ <>.and <c>.any <c>.any) + (function (_ extension phase archive [indexC arrayC]) + (do phase.monad + [indexA (analysis/type.with_type Nat + (phase archive indexC)) + [var_id varT] (analysis/type.with_env check.var) + arrayA (analysis/type.with_type (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.infer (type (Array varT)))] + (wrap (#analysis.Extension extension (list indexA arrayA)))))])) + +(def: bundle::array + Bundle + (<| (bundle.prefix "array") + (|> bundle.empty + (bundle.install "new" array::new) + (bundle.install "length" array::length) + (bundle.install "read" array::read) + (bundle.install "write" array::write) + (bundle.install "delete" array::delete) + ))) + +(def: Nil + (for {@.ruby host.Nil} + Any)) + +(def: Object + (for {@.ruby (type (host.Object Any))} + Any)) + +(def: Function + (for {@.ruby host.Function} + Any)) + +(def: object::get + Handler + (custom + [($_ <>.and <c>.text <c>.any) + (function (_ extension phase archive [fieldC objectC]) + (do phase.monad + [objectA (analysis/type.with_type ..Object + (phase archive objectC)) + _ (analysis/type.infer .Any)] + (wrap (#analysis.Extension extension (list (analysis.text fieldC) + objectA)))))])) + +(def: object::do + Handler + (custom + [($_ <>.and <c>.text <c>.any (<>.some <c>.any)) + (function (_ extension phase archive [methodC objectC inputsC]) + (do {! phase.monad} + [objectA (analysis/type.with_type ..Object + (phase archive objectC)) + inputsA (monad.map ! (|>> (phase archive) (analysis/type.with_type Any)) inputsC) + _ (analysis/type.infer .Any)] + (wrap (#analysis.Extension extension (list& (analysis.text methodC) + objectA + inputsA)))))])) + +(def: bundle::object + Bundle + (<| (bundle.prefix "object") + (|> bundle.empty + (bundle.install "get" object::get) + (bundle.install "do" object::do) + (bundle.install "nil" (/.nullary ..Nil)) + (bundle.install "nil?" (/.unary Any Bit)) + ))) + +(def: ruby::constant + Handler + (custom + [<c>.text + (function (_ extension phase archive name) + (do phase.monad + [_ (analysis/type.infer Any)] + (wrap (#analysis.Extension extension (list (analysis.text name))))))])) + +(def: ruby::apply + Handler + (custom + [($_ <>.and <c>.any (<>.some <c>.any)) + (function (_ extension phase archive [abstractionC inputsC]) + (do {! phase.monad} + [abstractionA (analysis/type.with_type ..Function + (phase archive abstractionC)) + inputsA (monad.map ! (|>> (phase archive) (analysis/type.with_type Any)) inputsC) + _ (analysis/type.infer Any)] + (wrap (#analysis.Extension extension (list& abstractionA inputsA)))))])) + +(def: ruby::import + Handler + (custom + [<c>.text + (function (_ extension phase archive name) + (do phase.monad + [_ (analysis/type.infer Bit)] + (wrap (#analysis.Extension extension (list (analysis.text name))))))])) + (def: #export bundle Bundle (<| (bundle.prefix "ruby") (|> bundle.empty + (dictionary.merge bundle::array) + (dictionary.merge bundle::object) + + (bundle.install "constant" ruby::constant) + (bundle.install "apply" ruby::apply) + (bundle.install "import" ruby::import) + (bundle.install "script universe" (/.nullary .Bit)) ))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby.lux index 8b1b94bbb..12bcfc9b1 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby.lux @@ -5,6 +5,7 @@ ["." dictionary]]]] ["." / #_ ["#." common] + ["#." host] [//// [generation [ruby @@ -12,4 +13,5 @@ (def: #export bundle Bundle - /common.bundle) + (dictionary.merge /common.bundle + /host.bundle)) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux index 9f04b35d2..50eddb998 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/common.lux @@ -47,34 +47,71 @@ (#try.Failure error) (/////.throw extension.invalid_syntax [extension_name %synthesis input])))) +## TODO: Get rid of this ASAP +(def: lux::syntax_char_case! + (..custom [($_ <>.and + <s>.any + <s>.any + (<>.some (<s>.tuple ($_ <>.and + (<s>.tuple (<>.many <s>.i64)) + <s>.any)))) + (function (_ extension_name phase archive [input else conditionals]) + (do {! /////.monad} + [inputG (phase archive input) + elseG (phase archive else) + @input (\ ! map _.local (generation.gensym "input")) + conditionalsG (: (Operation (List [Expression Expression])) + (monad.map ! (function (_ [chars branch]) + (do ! + [branchG (phase archive branch)] + (wrap [(|> chars + (list\map (|>> .int _.int (_.= @input))) + (list\fold (function (_ clause total) + (if (is? _.nil total) + clause + (_.or clause total))) + _.nil)) + branchG]))) + conditionals)) + #let [closure (_.lambda #.None (list @input) + (list\fold (function (_ [test then] else) + (_.if test (_.return then) else)) + (_.return elseG) + conditionalsG))]] + (wrap (_.apply_lambda/* (list inputG) closure))))])) + (def: lux_procs Bundle (|> /.empty - (/.install "is" (binary (product.uncurry _.=))) + (/.install "syntax char case!" lux::syntax_char_case!) + (/.install "is" (binary (function (_ [reference subject]) + (_.do "equal?" (list reference) subject)))) (/.install "try" (unary //runtime.lux//try)))) -(def: keep_i64 - (All [input] - (-> (-> input Expression) - (-> input Expression))) - (function.compose (_.bit_and (_.manual "0xFFFFFFFFFFFFFFFF")))) +(def: (capped operation parameter subject) + (-> (-> Expression Expression Expression) + (-> Expression Expression Expression)) + (//runtime.i64//64 (operation parameter subject))) (def: i64_procs Bundle (<| (/.prefix "i64") (|> /.empty - (/.install "and" (binary (product.uncurry _.bit_and))) - (/.install "or" (binary (product.uncurry _.bit_or))) - (/.install "xor" (binary (product.uncurry _.bit_xor))) - (/.install "left-shift" (binary (..keep_i64 (product.uncurry _.bit_shl)))) - (/.install "right-shift" (binary (product.uncurry //runtime.i64//logic_right_shift))) - (/.install "=" (binary (product.uncurry _.=))) - (/.install "+" (binary (..keep_i64 (product.uncurry _.+)))) - (/.install "-" (binary (..keep_i64 (product.uncurry _.-)))) + (/.install "and" (binary (product.uncurry //runtime.i64//and))) + (/.install "or" (binary (product.uncurry //runtime.i64//or))) + (/.install "xor" (binary (product.uncurry //runtime.i64//xor))) + (/.install "left-shift" (binary (product.uncurry //runtime.i64//left_shift))) + (/.install "right-shift" (binary (product.uncurry //runtime.i64//right_shift))) + (/.install "<" (binary (product.uncurry _.<))) - (/.install "*" (binary (..keep_i64 (product.uncurry _.*)))) - (/.install "/" (binary (product.uncurry _./))) - (/.install "%" (binary (product.uncurry _.%))) + (/.install "=" (binary (product.uncurry _.=))) + (/.install "+" (binary (product.uncurry (..capped _.+)))) + (/.install "-" (binary (product.uncurry (..capped _.-)))) + (/.install "*" (binary (product.uncurry (..capped _.*)))) + (/.install "/" (binary (product.uncurry //runtime.i64//division))) + (/.install "%" (binary (function (_ [parameter subject]) + (_.do "remainder" (list parameter) subject)))) + (/.install "f64" (unary (_./ (_.float +1.0)))) (/.install "char" (unary (_.do "chr" (list (_.string "UTF-8"))))) ))) @@ -87,10 +124,11 @@ (/.install "-" (binary (product.uncurry _.-))) (/.install "*" (binary (product.uncurry _.*))) (/.install "/" (binary (product.uncurry _./))) - (/.install "%" (binary (product.uncurry _.%))) + (/.install "%" (binary (function (_ [parameter subject]) + (_.do "remainder" (list parameter) subject)))) (/.install "=" (binary (product.uncurry _.=))) (/.install "<" (binary (product.uncurry _.<))) - (/.install "int" (unary (_.do "floor" (list)))) + (/.install "i64" (unary (_.do "floor" (list)))) (/.install "encode" (unary (_.do "to_s" (list)))) (/.install "decode" (unary //runtime.f64//decode))))) @@ -100,7 +138,7 @@ (def: (text//clip [paramO extraO subjectO]) (Trinary Expression) - (//runtime.text//clip subjectO paramO extraO)) + (//runtime.text//clip paramO extraO subjectO)) (def: (text//index [startO partO textO]) (Trinary Expression) @@ -112,7 +150,7 @@ (|> /.empty (/.install "=" (binary (product.uncurry _.=))) (/.install "<" (binary (product.uncurry _.<))) - (/.install "concat" (binary (product.uncurry _.+))) + (/.install "concat" (binary (product.uncurry (function.flip _.+)))) (/.install "index" (trinary text//index)) (/.install "size" (unary (_.the "length"))) (/.install "char" (binary (product.uncurry //runtime.text//char))) @@ -121,9 +159,8 @@ (def: (io//log! messageG) (Unary Expression) - (_.or (_.apply/* (list (|> messageG (_.+ (_.string text.new_line)))) - (_.local "puts")) - //runtime.unit)) + (_.or //runtime.unit + (_.print/2 messageG (_.string text.new_line)))) (def: io//error! (Unary Expression) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/host.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/host.lux new file mode 100644 index 000000000..206034cd7 --- /dev/null +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/ruby/host.lux @@ -0,0 +1,135 @@ +(.module: + [lux #* + [abstract + ["." monad (#+ do)]] + [control + ["." function] + ["<>" parser + ["<s>" synthesis (#+ Parser)]]] + [data + [collection + ["." dictionary] + ["." list]] + [text + ["%" format (#+ format)]]] + [target + ["_" ruby (#+ Var Expression)]]] + ["." // #_ + ["#." common (#+ custom)] + ["//#" /// #_ + ["/" bundle] + ["/#" // #_ + ["." extension] + [generation + [extension (#+ Nullary Unary Binary Trinary + nullary unary binary trinary)] + ["." reference] + ["//" ruby #_ + ["#." runtime (#+ Operation Phase Handler Bundle + with_vars)]]] + ["/#" // #_ + ["." generation] + ["//#" /// #_ + ["#." phase]]]]]]) + +(def: (array::new [size]) + (Unary Expression) + (_.do "new" (list size) (_.local "Array"))) + +(def: array::length + (Unary Expression) + (_.the "size")) + +(def: (array::read [indexG arrayG]) + (Binary Expression) + (_.nth indexG arrayG)) + +(def: (array::write [indexG valueG arrayG]) + (Trinary Expression) + (//runtime.array//write indexG valueG arrayG)) + +(def: (array::delete [indexG arrayG]) + (Binary Expression) + (//runtime.array//write indexG _.nil arrayG)) + +(def: array + Bundle + (<| (/.prefix "array") + (|> /.empty + (/.install "new" (unary array::new)) + (/.install "length" (unary array::length)) + (/.install "read" (binary array::read)) + (/.install "write" (trinary array::write)) + (/.install "delete" (binary array::delete)) + ))) + +(def: object::get + Handler + (custom + [($_ <>.and <s>.text <s>.any) + (function (_ extension phase archive [fieldS objectS]) + (do ////////phase.monad + [objectG (phase archive objectS)] + (wrap (_.the fieldS objectG))))])) + +(def: object::do + Handler + (custom + [($_ <>.and <s>.text <s>.any (<>.some <s>.any)) + (function (_ extension phase archive [methodS objectS inputsS]) + (do {! ////////phase.monad} + [objectG (phase archive objectS) + inputsG (monad.map ! (phase archive) inputsS)] + (wrap (_.do methodS inputsG objectG))))])) + +(template [<!> <?> <unit>] + [(def: <!> (Nullary Expression) (function.constant <unit>)) + (def: <?> (Unary Expression) (_.= <unit>))] + + [object::nil object::nil? _.nil] + ) + +(def: object + Bundle + (<| (/.prefix "object") + (|> /.empty + (/.install "get" object::get) + (/.install "do" object::do) + (/.install "nil" (nullary object::nil)) + (/.install "nil?" (unary object::nil?)) + ))) + +(def: ruby::constant + (custom + [<s>.text + (function (_ extension phase archive name) + (\ ////////phase.monad wrap (_.local name)))])) + +(def: ruby::apply + (custom + [($_ <>.and <s>.any (<>.some <s>.any)) + (function (_ extension phase archive [abstractionS inputsS]) + (do {! ////////phase.monad} + [abstractionG (phase archive abstractionS) + inputsG (monad.map ! (phase archive) inputsS)] + (wrap (_.apply/* inputsG abstractionG))))])) + +(def: ruby::import + (custom + [<s>.text + (function (_ extension phase archive module) + (\ ////////phase.monad wrap + (_.require/1 (_.string module))))])) + +(def: #export bundle + Bundle + (<| (/.prefix "ruby") + (|> /.empty + (dictionary.merge ..array) + (dictionary.merge ..object) + + (/.install "constant" ruby::constant) + (/.install "apply" ruby::apply) + (/.install "import" ruby::import) + (/.install "script universe" (nullary (function.constant (_.bool reference.universe)))) + ))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python.lux index cdaabfc08..2e86ad107 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python.lux @@ -26,8 +26,6 @@ [reference (#+) [variable (#+)]]]]]]]) -(exception: #export cannot-recur-as-an-expression) - (def: (statement expression archive synthesis) Phase! (case synthesis @@ -60,6 +58,8 @@ (//////phase\map _.return (/function.function statement expression archive abstraction)) )) +(exception: #export cannot-recur-as-an-expression) + (def: #export (expression archive synthesis) Phase (case synthesis diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/case.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/case.lux index eb6ae3e19..202e922c1 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/case.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/case.lux @@ -151,27 +151,29 @@ [right_choice (_.string "") inc] ) -(def: (alternation in_closure? g!once pre! post!) - (-> Bit SVar (Statement Any) (Statement Any) (Statement Any)) +(def: (with_looping in_closure? g!once body!) + (-> Bit SVar (Statement Any) (Statement Any)) (.if in_closure? - ($_ _.then - (_.while (_.bool true) - ($_ _.then - ..save! - pre!) - #.None) - ..restore! - post!) + (_.while (_.bool true) + body! + #.None) ($_ _.then (_.set (list g!once) (_.bool true)) (_.while g!once ($_ _.then (_.set (list g!once) (_.bool false)) - ..save! - pre!) - (#.Some _.continue)) - ..restore! - post!))) + body!) + (#.Some _.continue))))) + +(def: (alternation in_closure? g!once pre! post!) + (-> Bit SVar (Statement Any) (Statement Any) (Statement Any)) + ($_ _.then + (..with_looping in_closure? g!once + ($_ _.then + ..save! + pre!)) + ..restore! + post!)) (def: (pattern_matching' in_closure? statement expression archive) (-> Bit Phase! Phase Archive Path (Operation (Statement Any))) @@ -271,20 +273,10 @@ (do ///////phase.monad [pattern_matching! (pattern_matching' in_closure? statement expression archive pathP) g!once (..gensym "once")] - (wrap (.if in_closure? - ($_ _.then - (_.while (_.bool true) - pattern_matching! - #.None) - (_.raise (_.Exception/1 (_.string case.pattern_matching_error)))) - ($_ _.then - (_.set (list g!once) (_.bool true)) - (_.while g!once - ($_ _.then - (_.set (list g!once) (_.bool false)) - pattern_matching!) - (#.Some _.continue)) - (_.raise (_.Exception/1 (_.string case.pattern_matching_error)))))))) + (wrap ($_ _.then + (..with_looping in_closure? g!once + pattern_matching!) + (_.raise (_.Exception/1 (_.string case.pattern_matching_error))))))) (def: #export dependencies (-> Path (List SVar)) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux index 933bcf6b0..1638a64ca 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/python/runtime.lux @@ -247,8 +247,8 @@ test_recursion! (_.if is_last? ## Must recurse. ($_ _.then - (_.set (list sum) sum_value) - (_.set (list wantedTag) (_.- sum_tag wantedTag))) + (_.set (list wantedTag) (_.- sum_tag wantedTag)) + (_.set (list sum) sum_value)) no_match!)] (<| (_.while (_.bool true)) (_.cond (list [(_.= wantedTag sum_tag) @@ -272,31 +272,12 @@ @sum//get )) -(runtime: i64//+limit - (|> (_.int +1) - (_.bit_shl (_.int +63)) - (_.- (_.int +1)))) - -(runtime: i64//-limit - (_.- (|> (_.int +1) - (_.bit_shl (_.int +63))) - (_.int +0))) - -(runtime: i64//+iteration - (|> (_.int +1) - (_.bit_shl (_.int +64)))) - -(runtime: i64//-iteration - (|> ..i64//+iteration - _.negate)) - -(runtime: i64//+cap - (|> ..i64//+limit - (_.+ (_.int +1)))) - -(runtime: i64//-cap - (|> ..i64//-limit - (_.- (_.int +1)))) +(def: i64//+limit (_.manual "+0x7FFFFFFFFFFFFFFF")) +(def: i64//-limit (_.manual "-0x8000000000000000")) +(def: i64//+iteration (_.manual "+0x10000000000000000")) +(def: i64//-iteration (_.manual "-0x10000000000000000")) +(def: i64//+cap (_.manual "+0x8000000000000000")) +(def: i64//-cap (_.manual "-0x8000000000000001")) (runtime: (i64//64 input) (with_vars [temp] @@ -355,9 +336,9 @@ (_.return (_.- (|> subject (..i64//division param) (_.* param)) subject))) -(template [<runtime> <python>] +(template [<runtime> <host>] [(runtime: (<runtime> left right) - (_.return (..i64//64 (<python> (..as_nat left) (..as_nat right)))))] + (_.return (..i64//64 (<host> (..as_nat left) (..as_nat right)))))] [i64//and _.bit_and] [i64//or _.bit_or] @@ -378,12 +359,6 @@ (def: runtime//i64 (Statement Any) ($_ _.then - @i64//+limit - @i64//-limit - @i64//+iteration - @i64//-iteration - @i64//+cap - @i64//-cap @i64//64 @i64//nat_top @i64//left_shift diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby.lux index 9524441f2..f1a4e3c1c 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby.lux @@ -26,7 +26,41 @@ [reference (#+) [variable (#+)]]]]]]]) -(def: #export (generate archive synthesis) +(def: (statement expression archive synthesis) + Phase! + (case synthesis + (^template [<tag>] + [(^ (<tag> value)) + (//////phase\map _.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! false statement expression archive case) + + (^template [<tag> <generator>] + [(^ (<tag> value)) + (<generator> statement expression archive value)]) + ([////synthesis.branch/let /case.let!] + [////synthesis.branch/if /case.if!] + [////synthesis.loop/scope /loop.scope!] + [////synthesis.loop/recur /loop.recur!]) + + (^ (////synthesis.function/abstraction abstraction)) + (//////phase\map _.return (/function.function statement expression archive abstraction)) + )) + +(exception: #export cannot-recur-as-an-expression) + +(def: (expression archive synthesis) Phase (case synthesis (^template [<tag> <generator>] @@ -39,23 +73,32 @@ (^template [<tag> <generator>] [(^ (<tag> value)) - (<generator> generate archive value)]) + (<generator> expression archive value)]) ([////synthesis.variant /structure.variant] [////synthesis.tuple /structure.tuple] - [////synthesis.branch/case /case.case] [////synthesis.branch/let /case.let] [////synthesis.branch/if /case.if] [////synthesis.branch/get /case.get] - [////synthesis.loop/scope /loop.scope] - [////synthesis.loop/recur /loop.recur] - - [////synthesis.function/abstraction /function.function] [////synthesis.function/apply /function.apply]) + (^template [<tag> <generator>] + [(^ (<tag> value)) + (<generator> statement expression archive value)]) + ([////synthesis.branch/case /case.case] + [////synthesis.loop/scope /loop.scope] + [////synthesis.function/abstraction /function.function]) + + (^ (////synthesis.loop/recur _)) + (//////phase.throw ..cannot-recur-as-an-expression []) + (#////synthesis.Reference value) (//reference.reference /reference.system archive value) (#////synthesis.Extension extension) - (///extension.apply archive generate extension))) + (///extension.apply archive expression extension))) + +(def: #export generate + Phase + ..expression) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux index 428ac6279..e21957afe 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/case.lux @@ -35,6 +35,10 @@ [meta [archive (#+ Archive)]]]]]]]) +(def: #export (gensym prefix) + (-> Text (Operation LVar)) + (///////phase\map (|>> %.nat (format prefix) _.local) /////generation.next)) + (def: #export register (-> Register LVar) (|>> (///reference.local //reference.system) :assume)) @@ -54,6 +58,15 @@ (_.lambda #.None (list (..register register))) (_.apply_lambda/* (list valueO)))))) +(def: #export (let! statement expression archive [valueS register bodyS]) + (Generator! [Synthesis Register Synthesis]) + (do ///////phase.monad + [valueO (expression archive valueS) + bodyO (statement expression archive bodyS)] + (wrap ($_ _.then + (_.set (list (..register register)) valueO) + bodyO)))) + (def: #export (if expression archive [testS thenS elseS]) (Generator [Synthesis Synthesis Synthesis]) (do ///////phase.monad @@ -62,6 +75,16 @@ elseO (expression archive elseS)] (wrap (_.? testO thenO elseO)))) +(def: #export (if! statement expression archive [testS thenS elseS]) + (Generator! [Synthesis Synthesis Synthesis]) + (do ///////phase.monad + [test! (expression archive testS) + then! (statement expression archive thenS) + else! (statement expression archive elseS)] + (wrap (_.if test! + then! + else!)))) + (def: #export (get expression archive [pathP valueS]) (Generator [(List Member) Synthesis]) (do ///////phase.monad @@ -106,7 +129,13 @@ Statement (_.set (list @cursor) (|> @savepoint (_.do "pop" (list))))) -(def: fail! _.break) +(def: #export symbol + (_.symbol "lux_break")) + +(def: fail! + _.break + ## (_.throw/1 ..symbol) + ) (def: (multi_pop! pops) (-> Nat Statement) @@ -130,23 +159,44 @@ [right_choice (_.string "") inc] ) -(def: (alternation pre! post!) - (-> Statement Statement Statement) +(def: (with_looping in_closure? g!once g!continue? body!) + (-> Bit LVar LVar Statement Statement) + ## (_.catch ..symbol body!) + (.if in_closure? + ($_ _.then + (_.while (_.bool true) + body!)) + ($_ _.then + (_.set (list g!once) (_.bool true)) + (_.set (list g!continue?) (_.bool false)) + (<| (_.while (_.bool true)) + (_.if g!once + ($_ _.then + (_.set (list g!once) (_.bool false)) + body!) + ($_ _.then + (_.set (list g!continue?) (_.bool true)) + _.break))) + (_.when g!continue? + _.next))) + ) + +(def: (alternation in_closure? g!once g!continue? pre! post!) + (-> Bit LVar LVar Statement Statement Statement) ($_ _.then - (_.while (_.bool true) - ($_ _.then - ..save! - pre!)) - ($_ _.then - ..restore! - post!))) - -(def: (pattern_matching' expression archive) - (-> Phase Archive Path (Operation Statement)) + (with_looping in_closure? g!once g!continue? + ($_ _.then + ..save! + pre!)) + ..restore! + post!)) + +(def: (pattern_matching' in_closure? statement expression archive) + (-> Bit (Generator! Path)) (function (recur pathP) (.case pathP (#/////synthesis.Then bodyS) - (///////phase\map _.return (expression archive bodyS)) + (statement expression archive bodyS) #/////synthesis.Pop (///////phase\wrap ..pop!) @@ -221,58 +271,49 @@ (..multi_pop! (n.+ 2 extra_pops)) next!)))) - (^template [<tag> <combinator>] - [(^ (<tag> preP postP)) - (do ///////phase.monad - [pre! (recur preP) - post! (recur postP)] - (wrap (<combinator> pre! post!)))]) - ([/////synthesis.path/seq _.then] - [/////synthesis.path/alt ..alternation])))) - -(def: (pattern_matching expression archive pathP) - (-> Phase Archive Path (Operation Statement)) + (^ (/////synthesis.path/seq preP postP)) + (do ///////phase.monad + [pre! (recur preP) + post! (recur postP)] + (wrap ($_ _.then + pre! + post!))) + + (^ (/////synthesis.path/alt preP postP)) + (do ///////phase.monad + [pre! (recur preP) + post! (recur postP) + g!once (..gensym "once") + g!continue? (..gensym "continue")] + (wrap (..alternation in_closure? g!once g!continue? pre! post!))) + ))) + +(def: (pattern_matching in_closure? statement expression archive pathP) + (-> Bit (Generator! Path)) (do ///////phase.monad - [pattern_matching! (pattern_matching' expression archive pathP)] + [pattern_matching! (pattern_matching' in_closure? statement expression archive pathP) + g!once (..gensym "once") + g!continue? (..gensym "continue")] (wrap ($_ _.then - (_.while (_.bool true) - pattern_matching!) + (..with_looping in_closure? g!once g!continue? + pattern_matching!) (_.statement (_.raise (_.string case.pattern_matching_error))))))) -(def: #export dependencies - (-> Path (List LVar)) - (|>> case.storage - (get@ #case.dependencies) - set.to_list - (list\map (function (_ variable) - (.case variable - (#///////variable.Local register) - (..register register) - - (#///////variable.Foreign register) - (..capture register)))))) - -(def: #export (case expression archive [valueS pathP]) - (Generator [Synthesis Path]) +(def: #export (case! in_closure? statement expression archive [valueS pathP]) + (-> Bit (Generator! [Synthesis Path])) (do ///////phase.monad - [initG (expression archive valueS) - [[case_module case_artifact] pattern_matching!] (/////generation.with_new_context archive - (pattern_matching expression archive pathP)) - #let [## @case (_.local (///reference.artifact [case_module case_artifact])) - ## @dependencies+ (..dependencies (/////synthesis.path/seq (/////synthesis.path/then valueS) - ## pathP)) - ## directive (_.function @case @dependencies+ - ## ($_ _.then - ## (_.set (list @cursor) (_.array (list initG))) - ## (_.set (list @savepoint) (_.array (list))) - ## pattern_matching!)) - directive (_.lambda #.None (list) - ($_ _.then - (_.set (list @cursor) (_.array (list initG))) - (_.set (list @savepoint) (_.array (list))) - pattern_matching!))] - ## _ (/////generation.execute! directive) - ## _ (/////generation.save! (%.nat case_artifact) directive) - ] - ## (wrap (_.apply/* @dependencies+ @case)) - (wrap (_.apply_lambda/* (list) directive)))) + [stack_init (expression archive valueS) + pattern_matching! (pattern_matching in_closure? statement expression archive pathP)] + (wrap ($_ _.then + (_.set (list @cursor) (_.array (list stack_init))) + (_.set (list @savepoint) (_.array (list))) + pattern_matching! + )))) + +(def: #export (case statement expression archive case) + (-> Phase! (Generator [Synthesis Path])) + (|> case + (case! true statement expression archive) + (\ ///////phase.monad map + (|>> (_.lambda #.None (list)) + (_.apply_lambda/* (list)))))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux index e2ace391d..21d74f8cd 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux @@ -62,15 +62,12 @@ (def: input (|>> inc //case.register)) -(def: #export (function expression archive [environment arity bodyS]) - (Generator (Abstraction Synthesis)) +(def: #export (function statement expression archive [environment arity bodyS]) + (-> Phase! (Generator (Abstraction Synthesis))) (do {! ///////phase.monad} - [[[function_module function_artifact] bodyO] (/////generation.with_new_context archive - (do ! - [function_name (\ ! map ///reference.artifact - (/////generation.context archive))] - (/////generation.with_anchor (_.local function_name) - (expression archive bodyS)))) + [[[function_module function_artifact] body!] (/////generation.with_new_context archive + (/////generation.with_anchor 1 + (statement expression archive bodyS))) closureO+ (monad.map ! (expression archive) environment) #let [function_name (///reference.artifact [function_module function_artifact]) @curried (_.local "curried") @@ -90,9 +87,9 @@ ($_ _.then (_.set (list @num_args) (_.the "length" @curried)) (_.cond (list [(|> @num_args (_.= arityO)) - ($_ _.then - initialize! - (_.return bodyO))] + (<| (_.then initialize!) + //loop.with_scope + body!)] [(|> @num_args (_.> arityO)) (let [slice (.function (_ from to) (_.array_range from to @curried)) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux index 4bdf1bc55..a2df0884a 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/loop.lux @@ -4,7 +4,7 @@ ["." monad (#+ do)]] [data ["." product] - [text + ["." text ["%" format (#+ format)]] [collection ["." list ("#\." functor fold)] @@ -30,59 +30,66 @@ [reference ["#." variable (#+ Register)]]]]]]]) -(def: loop_name - (-> Nat LVar) - (|>> %.nat (format "loop") _.local)) +(def: (setup offset bindings body) + (-> Register (List Expression) Statement Statement) + (|> bindings + list.enumeration + (list\map (function (_ [register value]) + (_.set (list (//case.register (n.+ offset register))) + value))) + list.reverse + (list\fold _.then body))) -(def: #export (scope expression archive [start initsS+ bodyS]) - (Generator (Scope Synthesis)) +(def: symbol + (_.symbol "lux_continue")) + +(def: #export with_scope + (-> Statement Statement) + (_.while (_.bool true))) + +(def: #export (scope! statement expression archive [start initsS+ bodyS]) + (Generator! (Scope Synthesis)) (case initsS+ ## function/false/non-independent loop #.Nil - (expression archive bodyS) + (statement expression archive bodyS) ## true loop _ (do {! ///////phase.monad} - [@loop (\ ! map ..loop_name /////generation.next) - initsO+ (monad.map ! (expression archive) initsS+) - [[loop_module loop_artifact] bodyO] (/////generation.with_new_context archive - (do ! - [@loop (\ ! map (|>> ///reference.artifact _.local) - (/////generation.context archive))] - (/////generation.with_anchor @loop - (expression archive bodyS)))) - #let [@loop (|> [loop_module loop_artifact] ///reference.artifact _.local) - locals (|> initsS+ - list.enumeration - (list\map (|>> product.left (n.+ start) //case.register))) - actual_loop (_.statement - (_.lambda (#.Some @loop) locals - (_.return bodyO))) - [directive instantiation] (: [Statement Expression] - (case (|> (synthesis.path/then bodyS) - //case.dependencies - (set.from_list _.code_hash) - (set.difference (set.from_list _.code_hash locals)) - set.to_list) - #.Nil - [actual_loop - @loop] + [initsO+ (monad.map ! (expression archive) initsS+) + body! (/////generation.with_anchor start + (statement expression archive bodyS))] + (wrap (<| (..setup start initsO+) + ..with_scope + body!))))) - foreigns - [(_.statement - (_.lambda (#.Some @loop) foreigns - ($_ _.then - actual_loop - (_.return @loop)))) - (_.apply_lambda/* foreigns @loop)]))] - _ (/////generation.execute! directive) - _ (/////generation.save! (%.nat loop_artifact) directive)] - (wrap (_.apply_lambda/* initsO+ instantiation))))) +(def: #export (scope statement expression archive [start initsS+ bodyS]) + (-> Phase! (Generator (Scope Synthesis))) + (case initsS+ + ## function/false/non-independent loop + #.Nil + (expression archive bodyS) + + ## true loop + _ + (do {! ///////phase.monad} + [body! (scope! statement expression archive [start initsS+ bodyS])] + (wrap (|> body! + (_.lambda #.None (list)) + (_.apply_lambda/* (list))))))) -(def: #export (recur expression archive argsS+) - (Generator (List Synthesis)) +(def: #export (recur! statement expression archive argsS+) + (Generator! (List Synthesis)) (do {! ///////phase.monad} - [@scope /////generation.anchor - argsO+ (monad.map ! (expression archive) argsS+)] - (wrap (_.apply_lambda/* argsO+ @scope)))) + [offset /////generation.anchor + @temp (//case.gensym "lux_recur_values") + argsO+ (monad.map ! (expression archive) argsS+) + #let [re_binds (|> argsO+ + list.enumeration + (list\map (function (_ [idx _]) + (_.nth (_.int (.int idx)) @temp))))]] + (wrap ($_ _.then + (_.set (list @temp) (_.array argsO+)) + (..setup offset re_binds + _.next))))) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux index d74915164..01befb892 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux @@ -39,7 +39,7 @@ (template [<name> <base>] [(type: #export <name> - (<base> LVar Expression Statement))] + (<base> Register Expression Statement))] [Operation /////generation.Operation] [Phase /////generation.Phase] @@ -51,12 +51,10 @@ (-> Phase Archive i (Operation Expression))) (type: #export Phase! - (-> Phase Archive Synthesis (Operation (Statement Any)))) + (-> Phase Archive Synthesis (Operation Statement))) (type: #export (Generator! i) - (-> Phase! Phase Archive i (Operation (Statement Any)))) - -(def: prefix Text "LuxRuntime") + (-> Phase! Phase Archive i (Operation Statement))) (def: #export unit (_.string /////synthesis.unit)) @@ -196,8 +194,8 @@ test_recursion! (_.if is_last? ## Must recurse. ($_ _.then - (_.set (list sum) sum_value) - (_.set (list wantedTag) (_.- sum_tag wantedTag))) + (_.set (list wantedTag) (_.- sum_tag wantedTag)) + (_.set (list sum) sum_value)) no_match!)] (<| (_.while (_.bool true)) (_.cond (list [(_.= sum_tag wantedTag) @@ -245,18 +243,76 @@ @lux//program_args )) -(runtime: (i64//logic_right_shift param subject) - (let [mask (|> (_.int +1) - (_.bit_shl (_.- param (_.int +64))) - (_.- (_.int +1)))] +(def: i64//+limit (_.manual "+0x7FFFFFFFFFFFFFFF")) +(def: i64//-limit (_.manual "-0x8000000000000000")) +(def: i64//+iteration (_.manual "+0x10000000000000000")) +(def: i64//-iteration (_.manual "-0x10000000000000000")) +(def: i64//+cap (_.manual "+0x8000000000000000")) +(def: i64//-cap (_.manual "-0x8000000000000001")) + +(runtime: (i64//64 input) + (with_vars [temp] + (`` (<| (~~ (template [<scenario> <iteration> <cap> <entrance>] + [(_.if (|> input <scenario>) + ($_ _.then + (_.set (list temp) (_.% <iteration> input)) + (_.return (_.? (|> temp <scenario>) + (|> temp (_.- <cap>) (_.+ <entrance>)) + temp))))] + + [(_.> ..i64//+limit) ..i64//+iteration ..i64//+cap ..i64//-limit] + [(_.< ..i64//-limit) ..i64//-iteration ..i64//-cap ..i64//+limit] + )) + (_.return input))))) + +(runtime: i64//nat_top + (|> (_.int +1) + (_.bit_shl (_.int +64)) + (_.- (_.int +1)))) + +(def: as_nat + (_.% (_.manual "0x10000000000000000"))) + +(runtime: (i64//left_shift param subject) + (_.return (|> subject + (_.bit_shl (_.% (_.int +64) param)) + ..i64//64))) + +(runtime: (i64//right_shift param subject) + ($_ _.then + (_.set (list param) (_.% (_.int +64) param)) + (_.return (_.? (_.= (_.int +0) param) + subject + (|> subject + ..as_nat + (_.bit_shr param)))))) + +(template [<runtime> <host>] + [(runtime: (<runtime> left right) + (_.return (..i64//64 (<host> (..as_nat left) (..as_nat right)))))] + + [i64//and _.bit_and] + [i64//or _.bit_or] + [i64//xor _.bit_xor] + ) + +(runtime: (i64//division parameter subject) + (let [extra (_.do "remainder" (list parameter) subject)] (_.return (|> subject - (_.bit_shr param) - (_.bit_and mask))))) + (_.- extra) + (_./ parameter))))) (def: runtime//i64 Statement ($_ _.then - @i64//logic_right_shift + @i64//64 + @i64//nat_top + @i64//left_shift + @i64//right_shift + @i64//and + @i64//or + @i64//xor + @i64//division )) (runtime: (f64//decode inputG) @@ -291,13 +347,15 @@ (_.and (|> value (_.>= (_.int +0))) (|> value (_.< top)))) -(runtime: (text//clip @text @from @to) - (_.return (|> @text (_.array_range @from @to)))) +(runtime: (text//clip offset length text) + (_.if (_.= (_.int +0) length) + (_.return (_.string "")) + (_.return (_.array_range offset (_.+ offset (_.- (_.int +1) length)) text)))) (runtime: (text//char idx text) (_.if (|> idx (within? (_.the "length" text))) - (_.return (..some (|> text (_.array_range idx idx) (_.do "ord" (list))))) - (_.return ..none))) + (_.return (|> text (_.array_range idx idx) (_.do "ord" (list)))) + (_.statement (_.raise (_.string "[Lux Error] Cannot get char from text."))))) (def: runtime//text Statement @@ -307,6 +365,17 @@ @text//char )) +(runtime: (array//write idx value array) + ($_ _.then + (_.set (list (_.nth idx array)) value) + (_.return array))) + +(def: runtime//array + Statement + ($_ _.then + @array//write + )) + (def: runtime Statement ($_ _.then @@ -315,11 +384,9 @@ runtime//i64 runtime//f64 runtime//text + runtime//array )) -(def: #export artifact - ..prefix) - (def: #export generate (Operation [Registry Output]) (do ///////phase.monad |