From cde758769d8950fa1f5a13aebea62be3b9602d98 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 14 Mar 2021 15:12:26 -0400 Subject: Frustrated with PHP's overflow/underflow logic. --- compilers.md | 2 + documentation/bookmark/Optimization.md | 1 + documentation/bookmark/Security.md | 1 + documentation/bookmark/browser.md | 1 + documentation/bookmark/debugging.md | 1 + documentation/bookmark/floating point.md | 4 ++ documentation/bookmark/law.md | 5 ++ documentation/bookmark/user_interface/graphic.md | 1 + documentation/bookmark/web_framework.md | 2 + lux-php/source/program.lux | 12 +---- stdlib/source/lux/data/collection/row.lux | 3 ++ stdlib/source/lux/math/number/nat.lux | 25 ++++----- stdlib/source/lux/target/php.lux | 4 +- .../lux/phase/extension/generation/php/host.lux | 6 +-- .../language/lux/phase/generation/php/loop.lux | 14 +++-- .../language/lux/phase/generation/php/runtime.lux | 59 ++++++++++++++-------- 16 files changed, 84 insertions(+), 57 deletions(-) create mode 100644 documentation/bookmark/law.md diff --git a/compilers.md b/compilers.md index ae558bbea..996322c7c 100644 --- a/compilers.md +++ b/compilers.md @@ -31,6 +31,8 @@ cd ~/lux/lux-php/ \ cd ~/lux/stdlib/ \ && lein clean \ && time java -jar ~/lux/lux-php/target/program.jar build --source ~/lux/stdlib/source --target ~/lux/stdlib/target --module test/lux + +php -f ~/lux/stdlib/target/program.php ``` --- diff --git a/documentation/bookmark/Optimization.md b/documentation/bookmark/Optimization.md index e31686963..4fb4656c9 100644 --- a/documentation/bookmark/Optimization.md +++ b/documentation/bookmark/Optimization.md @@ -12,6 +12,7 @@ # Reference +1. [Towards a Domain-Extensible Compiler: Optimizingan Image Processing Pipeline on Mobile CPUs](https://thok.eu/publications/2021/cgo.pdf) 1. [Compiler Detection of Function Call Side Effects](https://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=B3D92D05C88C3D9C165785594350C169?doi=10.1.1.70.2096&rep=rep1&type=pdf) 1. [A Language for Describing Optimization Strategies](https://arxiv.org/abs/2002.02268) 1. https://docs.google.com/presentation/d/1tpeJZFObkeick4CF-mx0L3CeCgvT15B96aJeRpxEPcE/preview?slide=id.p diff --git a/documentation/bookmark/Security.md b/documentation/bookmark/Security.md index b9d45faff..4ea9b1b46 100644 --- a/documentation/bookmark/Security.md +++ b/documentation/bookmark/Security.md @@ -4,6 +4,7 @@ # Privacy +1. [Programming Differential Privacy](https://uvm-plaid.github.io/programming-dp/intro.html) 1. https://privacypatterns.org/ # Inspiration diff --git a/documentation/bookmark/browser.md b/documentation/bookmark/browser.md index 7579e468b..2521275e8 100644 --- a/documentation/bookmark/browser.md +++ b/documentation/bookmark/browser.md @@ -46,4 +46,5 @@ 1. https://v8project.blogspot.com/2018/08/embedded-builtins.html 1. https://developers.google.com/web/updates/2018/09/inside-browser-part1 1. https://addons.mozilla.org/en-US/firefox/addon/tree-style-tab/ +1. [Web Browser Engineering](https://browser.engineering/index.html) diff --git a/documentation/bookmark/debugging.md b/documentation/bookmark/debugging.md index 99071f483..f870c5d94 100644 --- a/documentation/bookmark/debugging.md +++ b/documentation/bookmark/debugging.md @@ -32,6 +32,7 @@ # Reference +1. [The Debugging Book: Tools and Techniques for Automated Software Debugging](https://www.debuggingbook.org/) 1. [The Power Of Collaborative Debugging](https://robert.ocallahan.org/2019/11/the-power-of-collaborative-debugging.html) 1. [Multiverse Debugging: Non-Deterministic Debugging for Non-Deterministic Programs](https://stefan-marr.de/2019/07/what-if-we-could-see-all-concurrency-bugs-in-the-debugger/) 1. [Writing a Debugger](http://system.joekain.com/debugger/) diff --git a/documentation/bookmark/floating point.md b/documentation/bookmark/floating point.md index 9268449d9..93921b0a9 100644 --- a/documentation/bookmark/floating point.md +++ b/documentation/bookmark/floating point.md @@ -1,3 +1,7 @@ +# Reference + +1. [What aspect of portable floating point did Java back down on?](https://retrocomputing.stackexchange.com/questions/18143/what-aspect-of-portable-floating-point-did-java-back-down-on) + # Algorithm 1. [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm) diff --git a/documentation/bookmark/law.md b/documentation/bookmark/law.md new file mode 100644 index 000000000..39a2b18fb --- /dev/null +++ b/documentation/bookmark/law.md @@ -0,0 +1,5 @@ +# Reference + +1. [Catala: A Programming Language for the Law](https://arxiv.org/abs/2103.03198) +1. []() + diff --git a/documentation/bookmark/user_interface/graphic.md b/documentation/bookmark/user_interface/graphic.md index 9b53bddae..51e78c16d 100644 --- a/documentation/bookmark/user_interface/graphic.md +++ b/documentation/bookmark/user_interface/graphic.md @@ -10,6 +10,7 @@ 1. [Ant Design](https://ant.design/) 1. [7 Practical Tips for Cheating at Design](https://medium.com/refactoring-ui/7-practical-tips-for-cheating-at-design-40c736799886) +1. [Smart progress bars](https://honeypot.net/post/smart-progress-bars/) # Dark Patterns diff --git a/documentation/bookmark/web_framework.md b/documentation/bookmark/web_framework.md index 741895072..76485f924 100644 --- a/documentation/bookmark/web_framework.md +++ b/documentation/bookmark/web_framework.md @@ -139,6 +139,8 @@ 1. https://medium.com/@devdevcharlie/things-nobody-ever-taught-me-about-css-5d16be8d5d0e 1. https://medium.freecodecamp.org/the-css-handbook-a-handy-guide-to-css-for-developers-b56695917d11 1. https://css-tricks.com/look-ma-no-media-queries-responsive-layouts-using-css-grid/ +1. [You want enabling CSS selectors, not disabling ones](https://www.silvestar.codes/articles/you-want-a-single-enabling-selector-not-the-one-that-disables-the-rule-of-the-previous-one/) +1. []() # Design system diff --git a/lux-php/source/program.lux b/lux-php/source/program.lux index 14a1646a0..a13039760 100644 --- a/lux-php/source/program.lux +++ b/lux-php/source/program.lux @@ -555,14 +555,6 @@ (-> Any (Promise Any)) (promise.future (\ world/program.default exit +0))) -(def: (scope body) - (-> _.Statement _.Statement) - (let [@program (_.constant "lux_program")] - ($_ _.then - (_.define_function @program (list) body) - (_.; (_.apply/* (list) @program)) - ))) - (`` (program: [{service /cli.service}] (let [extension ".php"] (do io.monad @@ -581,10 +573,10 @@ [(& Nat _.Label) _.Expression _.Statement] ..extender service - [(packager.package (_.manual "") + [(packager.package (_.manual ">)) (format (/cli.target service) (\ file.default separator) "program" diff --git a/stdlib/source/lux/data/collection/row.lux b/stdlib/source/lux/data/collection/row.lux index 560f7618a..dd1cbcc42 100644 --- a/stdlib/source/lux/data/collection/row.lux +++ b/stdlib/source/lux/data/collection/row.lux @@ -1,3 +1,6 @@ +## https://hypirion.com/musings/understanding-persistent-vector-pt-1 +## https://hypirion.com/musings/understanding-persistent-vector-pt-2 +## https://hypirion.com/musings/understanding-persistent-vector-pt-3 (.module: [lux #* ["@" target] diff --git a/stdlib/source/lux/math/number/nat.lux b/stdlib/source/lux/math/number/nat.lux index 7edc60be4..d0fb348fa 100644 --- a/stdlib/source/lux/math/number/nat.lux +++ b/stdlib/source/lux/math/number/nat.lux @@ -287,22 +287,15 @@ (def: (hexadecimal-value digit) (-> Nat (Maybe Nat)) (case digit - (^ (char "0")) (#.Some 0) - (^ (char "1")) (#.Some 1) - (^ (char "2")) (#.Some 2) - (^ (char "3")) (#.Some 3) - (^ (char "4")) (#.Some 4) - (^ (char "5")) (#.Some 5) - (^ (char "6")) (#.Some 6) - (^ (char "7")) (#.Some 7) - (^ (char "8")) (#.Some 8) - (^ (char "9")) (#.Some 9) - (^or (^ (char "a")) (^ (char "A"))) (#.Some 10) - (^or (^ (char "b")) (^ (char "B"))) (#.Some 11) - (^or (^ (char "c")) (^ (char "C"))) (#.Some 12) - (^or (^ (char "d")) (^ (char "D"))) (#.Some 13) - (^or (^ (char "e")) (^ (char "E"))) (#.Some 14) - (^or (^ (char "f")) (^ (char "F"))) (#.Some 15) + (^template [ ] + [(^ (char )) (#.Some )]) + (["0" 0] ["1" 1] ["2" 2] ["3" 3] ["4" 4] + ["5" 5] ["6" 6] ["7" 7] ["8" 8] ["9" 9]) + + (^template [ ] + [(^or (^ (char )) (^ (char ))) (#.Some )]) + (["a" "A" 10] ["b" "B" 11] ["c" "C" 12] + ["d" "D" 13] ["e" "E" 14] ["f" "F" 15]) _ #.None)) (template [ ] diff --git a/stdlib/source/lux/target/php.lux b/stdlib/source/lux/target/php.lux index b1eb0b553..f76d9cdc0 100644 --- a/stdlib/source/lux/target/php.lux +++ b/stdlib/source/lux/target/php.lux @@ -267,7 +267,8 @@ ["phpversion"]]] [1 - [["var_dump"] + [["isset"] + ["var_dump"] ["is_null"] ["empty"] ["count"] @@ -284,6 +285,7 @@ [2 [["intdiv"] + ["array_key_exists"] ["call_user_func_array"] ["array_slice"] ["array_push"] diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/host.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/host.lux index f523f1647..794d4aff2 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/host.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/extension/generation/php/host.lux @@ -36,10 +36,6 @@ (Unary Expression) (//runtime.tuple//make size (_.array_fill/3 [(_.int +0) size _.null]))) -(def: array::length - (Unary Expression) - //runtime.array//length) - (def: (array::read [indexG arrayG]) (Binary Expression) (_.nth indexG arrayG)) @@ -57,7 +53,7 @@ (<| (/.prefix "array") (|> /.empty (/.install "new" (unary array::new)) - (/.install "length" (unary array::length)) + (/.install "length" (unary //runtime.array//length)) (/.install "read" (binary array::read)) (/.install "write" (trinary array::write)) (/.install "delete" (binary array::delete)) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux index 30e325363..d3e91b925 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/loop.lux @@ -8,7 +8,7 @@ ["%" format (#+ format)]] [collection ["." list ("#\." functor fold)] - ["." set]]] + ["." set (#+ Set)]]] [math [number ["n" nat]]] @@ -81,11 +81,15 @@ list.enumeration (list\map (|>> product.left (n.+ start) //case.register _.parameter))) @loop (_.constant (///reference.artifact [loop_module loop_artifact])) + loop_variables (set.from_list _.hash (list\map product.right locals)) + referenced_variables (: (-> Synthesis (Set Var)) + (|>> synthesis.path/then + //case.dependencies + (set.from_list _.hash))) [directive instantiation] (: [Statement Expression] - (case (|> (synthesis.path/then bodyS) - //case.dependencies - (set.from_list _.hash) - (set.difference (set.from_list _.hash (list\map product.right locals))) + (case (|> (list\map referenced_variables initsS+) + (list\fold set.union (referenced_variables bodyS)) + (set.difference loop_variables) set.to_list) #.Nil [(_.define_function @loop (list) scope!) diff --git a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux index 5e1c36112..bdf18462a 100644 --- a/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux +++ b/stdlib/source/lux/tool/compiler/language/lux/phase/generation/php/runtime.lux @@ -149,7 +149,7 @@ (def: #export tuple_size_field "_lux_size") -(def: #export tuple_size +(def: tuple_size (_.nth (_.string ..tuple_size_field))) (def: jphp? @@ -158,9 +158,7 @@ (runtime: (array//length array) ## TODO: Get rid of this as soon as JPHP is no longer necessary. (_.if ..jphp? - (_.if (..tuple_size array) - (_.return (..tuple_size array)) - (_.return (_.count/1 array))) + (_.return (..tuple_size array)) (_.return (_.count/1 array)))) (runtime: (array//write idx value array) @@ -175,22 +173,34 @@ @array//write )) -(def: last_index +(def: jphp_last_index (|>> ..tuple_size (_.- (_.int +1)))) +(def: normal_last_index + (|>> _.count/1 (_.- (_.int +1)))) + (with_expansions [ (as_is ($_ _.then (_.; (_.set lefts (_.- last_index_right lefts))) (_.; (_.set tuple (_.nth last_index_right tuple)))))] (runtime: (tuple//make size values) - ($_ _.then - (_.; (_.set (..tuple_size values) size)) - (_.return values))) + (_.if ..jphp? + ($_ _.then + (_.; (_.set (..tuple_size values) size)) + (_.return values)) + ## https://www.php.net/manual/en/language.operators.assignment.php + ## https://www.php.net/manual/en/language.references.php + ## https://www.php.net/manual/en/functions.arguments.php + ## https://www.php.net/manual/en/language.oop5.references.php + ## https://www.php.net/manual/en/class.arrayobject.php + (_.return (_.new (_.constant "ArrayObject") (list values))))) (runtime: (tuple//left lefts tuple) (with_vars [last_index_right] (<| (_.while (_.bool true)) ($_ _.then - (_.; (_.set last_index_right (..last_index tuple))) + (_.if ..jphp? + (_.; (_.set last_index_right (..jphp_last_index tuple))) + (_.; (_.set last_index_right (..normal_last_index tuple)))) (_.if (_.> lefts last_index_right) ## No need for recursion (_.return (_.nth lefts tuple)) @@ -216,7 +226,9 @@ (with_vars [last_index_right right_index] (<| (_.while (_.bool true)) ($_ _.then - (_.; (_.set last_index_right (..last_index tuple))) + (_.if ..jphp? + (_.; (_.set last_index_right (..jphp_last_index tuple))) + (_.; (_.set last_index_right (..normal_last_index tuple)))) (_.; (_.set right_index (_.+ (_.int +1) lefts))) (_.cond (list [(_.=== last_index_right right_index) (_.return (_.nth right_index tuple))] @@ -226,7 +238,7 @@ (_.if ..jphp? (_.return (..tuple//make (_.- right_index (..tuple_size tuple)) (..tuple//slice right_index tuple))) - (_.return (..tuple//make (_.- right_index (..tuple_size tuple)) + (_.return (..tuple//make (_.- right_index (_.count/1 tuple)) (_.array_slice/2 [tuple right_index]))))) ))))) @@ -326,16 +338,23 @@ )) (runtime: (i64//right_shift param subject) - (let [mask (|> (_.int +1) - (_.bit_shl (_.- param (_.int +64))) - (_.- (_.int +1)))] + (let [## The mask has to be calculated this way instead of in a more straightforward way + ## because in some languages, 1<<63 = max_negative_value + ## and max_negative_value-1 = max_positive_value. + ## And bitwise, max_positive_value works out to the mask that is desired when param = 0. + ## However, in PHP, max_negative_value-1 underflows and gets cast into a float. + ## And this messes up the computation. + ## This slightly more convoluted calculation avoids that problem. + mask (|> (_.int +1) + (_.bit_shl (_.- param (_.int +63))) + (_.- (_.int +1)) + (_.bit_shl (_.int +1)) + (_.+ (_.int +1)))] ($_ _.then - (_.; (_.set param (_.bit_and (_.int +63) param))) - (_.if (_.=== (_.int +0) param) - (_.return subject) - (_.return (|> subject - (_.bit_and mask) - (_.bit_shr param))))))) + (_.; (_.set param (_.% (_.int +64) param))) + (_.return (|> subject + (_.bit_shr param) + (_.bit_and mask)))))) (runtime: (i64//char code) (_.if ..jphp? -- cgit v1.2.3