diff -Nru rakudo-2018.10/Configure.pl rakudo-2018.12/Configure.pl --- rakudo-2018.10/Configure.pl 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/Configure.pl 2018-12-21 05:16:35.000000000 +0000 @@ -361,7 +361,7 @@ sorry($options{'ignore-errors'}, @errors) if @errors; my $l = uc $backend_prefix{$default_backend}; - print $MAKEFILE qq[\nt/*/*.t t/*.t t/*/*/*.t: all\n\t\$(${l}_HARNESS_WITH_FUDGE) --verbosity=1 \$\@\n]; + print $MAKEFILE qq[\nt/*/*.t t/*.t t/*/*/*.t: all\n\t\$(${l}_HARNESS5_WITH_FUDGE) --verbosity=1 \$\@\n]; close $MAKEFILE or die "Cannot write 'Makefile': $!"; diff -Nru rakudo-2018.10/CREDITS rakudo-2018.12/CREDITS --- rakudo-2018.10/CREDITS 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/CREDITS 2018-12-21 05:16:35.000000000 +0000 @@ -98,6 +98,11 @@ E: bartwiegmans@gmail.com D: Hack MoarVM JIT stuff +N: Ben Davies +U: Kaiepi +E: kaiepi@outlook.com +D: Improving *BSD and networking support + N: Bernhard Schmalhofer U: bernhard E: Bernhard.Schmalhofer@gmx.de @@ -317,11 +322,6 @@ W: http://fperrad.googlepages.com/home U: fperrad -N: M. Faiz Zakwan Zamzuri -E: skelic3@gmail.com -U: faraco -W: https://faracosite.wordpress.com - N: Gabor Szabo E: szabgab@gmail.com @@ -603,6 +603,10 @@ N: Mouq E: alexmoquin@gmail.com +N: Momo +E: skelic3@gmail.com +U: momozor + N: Nicholas Clark U: nicholas E: nick@ccl4.org @@ -641,6 +645,7 @@ E: paul@liekut.de N: Paweł Murias +N: Pawel Murias U: pmurias E: pawelmurias@gmail.com diff -Nru rakudo-2018.10/debian/changelog rakudo-2018.12/debian/changelog --- rakudo-2018.10/debian/changelog 2018-11-15 20:15:18.000000000 +0000 +++ rakudo-2018.12/debian/changelog 2019-01-09 17:59:57.000000000 +0000 @@ -1,3 +1,42 @@ +rakudo (2018.12-5) unstable; urgency=medium + + * Execute last test run without spesh + + -- Robert Lemmen Wed, 09 Jan 2019 18:59:57 +0100 + +rakudo (2018.12-4) unstable; urgency=medium + + * Run tests more often on failures to get data on flappers + + -- Robert Lemmen Fri, 04 Jan 2019 20:02:29 +0100 + +rakudo (2018.12-3) unstable; urgency=medium + + * Remove unused libreadline dependency + + -- Robert Lemmen Mon, 31 Dec 2018 10:52:35 +0100 + +rakudo (2018.12-2) unstable; urgency=medium + + * No longer fail if precomp files do not exist on removal (closes: #916646) + * Make vendor/resources explicit in package (closes: #915785) + + -- Robert Lemmen Sun, 30 Dec 2018 12:54:52 +0100 + +rakudo (2018.12-1) unstable; urgency=medium + + * New upstream version 2018.12 + * control: update moarvm-dev and nqp dep versions + + -- Robert Lemmen Sat, 22 Dec 2018 14:51:21 +0100 + +rakudo (2018.11-1) unstable; urgency=medium + + * New upstream version 2018.11 + * control: update moarvm-dev and nqp dep versions + + -- Robert Lemmen Sat, 01 Dec 2018 19:09:33 +0100 + rakudo (2018.10-1) unstable; urgency=medium * New upstream version 2018.10 diff -Nru rakudo-2018.10/debian/control rakudo-2018.12/debian/control --- rakudo-2018.10/debian/control 2018-11-15 20:14:30.000000000 +0000 +++ rakudo-2018.12/debian/control 2018-12-31 09:45:19.000000000 +0000 @@ -10,11 +10,10 @@ libffi-dev [mipsel], libgmp-dev, libkvm-dev [kfreebsd-any], - libreadline-dev, libtommath-dev, libuv1-dev, - moarvm-dev (>= 2018.10), - nqp (>= 2018.10), + moarvm-dev (>= 2018.12), + nqp (>= 2018.12), perl Standards-Version: 4.1.4 Vcs-Browser: https://salsa.debian.org/perl6-team/rakudo diff -Nru rakudo-2018.10/debian/rakudo-helper.pl.template rakudo-2018.12/debian/rakudo-helper.pl.template --- rakudo-2018.10/debian/rakudo-helper.pl.template 2018-11-15 20:08:36.000000000 +0000 +++ rakudo-2018.12/debian/rakudo-helper.pl.template 2018-12-30 11:53:43.000000000 +0000 @@ -65,20 +65,22 @@ sub remove($) { my ($module) = @_; - debug_say("removing perl6 module $module..."); - my $fh; - open($fh, "< $varlib/$module.list") - or die "could not open file in removal of module $module: $!"; - while (<$fh>) { - chomp; - # XXX this feels a bit unsafe... - unlink "$vendor/$_"; + if (-e "$varlib/$module.list") { + debug_say("removing perl6 module $module..."); + my $fh; + open($fh, "< $varlib/$module.list") + or die "could not open file in removal of module $module: $!"; + while (<$fh>) { + chomp; + # XXX this feels a bit unsafe... + unlink "$vendor/$_"; + } + close($fh); + unlink "$varlib/$module.list"; + my @cmd = qq!find $vendor/short $vendor/precomp $vendor/dist $vendor/sources -type d -empty -delete!; + system(@cmd) == 0 + or die "could not remove empty directories in removal of module $module: $?"; } - close($fh); - unlink "$varlib/$module.list"; - my @cmd = qq!find $vendor/short $vendor/precomp $vendor/dist $vendor/sources -type d -empty -delete!; - system(@cmd) == 0 - or die "could not remove empty directories in removal of module $module: $?"; } sub reinstall_all() { diff -Nru rakudo-2018.10/debian/rules rakudo-2018.12/debian/rules --- rakudo-2018.10/debian/rules 2018-11-15 20:08:36.000000000 +0000 +++ rakudo-2018.12/debian/rules 2019-01-09 17:59:15.000000000 +0000 @@ -46,6 +46,10 @@ cat debian/rakudo-helper.pl.template | sed -e "s/__COMPILER_ID__/$$RAKUDO_COMPILER_ID/" > $(INSTALL)/usr/share/perl6/rakudo-helper.pl chmod +x $(INSTALL)/usr/share/perl6/rakudo-helper.pl mkdir -p $(INSTALL)/var/lib/perl6/modules - mkdir -p $(INSTALL)/usr/share/perl6/vendor + mkdir -p $(INSTALL)/usr/share/perl6/vendor/resources mkdir -p $(INSTALL)/usr/share/perl6/debian-sources +# we curretnly (2018.12) want to run the tests multiple times on failures, to +# get more data on flappers +override_dh_auto_test: + make test || make test || make test || make test || MVM_SPESH_DISABLE=1 make test diff -Nru rakudo-2018.10/docs/announce/2018.10.md rakudo-2018.12/docs/announce/2018.10.md --- rakudo-2018.10/docs/announce/2018.10.md 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/docs/announce/2018.10.md 2018-12-21 05:16:35.000000000 +0000 @@ -43,7 +43,7 @@ + Fixed indexing of shaped arrays with a dimension higher than 3 [0307c366] + `.in-timezone`s value is now coerced to Int [c8438e6a] + Stub methods from roles are now verified [fd5d5bdf] - + Fixed double-closing of handles in `.lines` when `:close` and + + Fixed double-closing of handles in `IO::Handle.lines` when `:close` and `$limit` are used [6edb142f] + Fixed closing of handles in `IO::Handle.lines` when `$limit` is used [c1c75740] @@ -87,14 +87,14 @@ + Other minor optimizations [464a86b1][ab83b9d8][8cc3d5d7][b107cda5] + Internal: + Made `make` an only [369068ae] - + Added skip-one method to appropriate PredictiveIterators [e54885e5] + + Added skip-one method to appropriate `PredictiveIterator`s [e54885e5] + More things are now initialized at setting compile time [06dfbf02][688cbac1][92735770] + Simplified initialization of `CompUnit::RepositoryRegistry` [0425d927][8e1cd01a] + Introduced `IterationBuffer.List` [8c10da6a] - + Made it not go through `.new` if we can `nqp::create` [84311b77] - + Made sure `.STORE` only works on instances [9daac683] + + Use `nqp::create` for IterationBuffer instead of .new [84311b77] + + Made sure `.STORE` only works on instances of mixy/baggy types [9daac683] + Added `$*INSIDE-EVAL` to mark that we're inside an `EVAL` [73b7c603] diff -Nru rakudo-2018.10/docs/announce/2018.11.md rakudo-2018.12/docs/announce/2018.11.md --- rakudo-2018.10/docs/announce/2018.11.md 1970-01-01 00:00:00.000000000 +0000 +++ rakudo-2018.12/docs/announce/2018.11.md 2018-12-21 05:16:35.000000000 +0000 @@ -0,0 +1,143 @@ +# Announce: Rakudo Perl 6 compiler, Release #128 (2018.11) + +On behalf of the Rakudo development team, I’m very happy to announce the +November 2018 release of Rakudo Perl 6 #128. Rakudo is an implementation of +Perl 6 on the Moar Virtual Machine[^1]. + +This release implements 6.c and 6.d versions of the Perl 6 specification. +6.c version of the language is available if you use the `use v6.c` +version pragma, otherwise 6.d is the default. + +Upcoming releases in 2018 will include new functionality that is not +part of 6.c or 6.d specifications, available with a lexically scoped +pragma. Our goal is to ensure that anything that is tested as part of +6.c and 6.d specifications will continue to work unchanged. There may +be incremental spec releases this year as well. + +The tarball for this release is available from . + +Please note: This announcement is not for the Rakudo Star +distribution[^2] — it’s announcing a new release of the compiler +only. For the latest Rakudo Star release, see +. + +The changes in this release are outlined below: + +New in 2018.11: + + SPECIAL NOTES: + + 🎆❇️🔥 Default language version is now `v6.d` 🔥❇️🎆 [46ef0ea0] + + Deprecations: + + Deprecated `.path`/`.args` in `Proc::Async`, use `.command` + instead [45bbc946] + + Fixes: + + Fixed `$*PERL.version` to always report the right version [c9ecfb7a] + + Consistified `:U.pairup` with `:D.pairup` to return a Seq [d73272e4] + + Provided a stable `.WHICH` for `Map` [4e0a1c24][052067fd] + + Made sure `DEPRECATED` reports location correctly when + using `:up` [8561d0ae] + + Fixed literal `\` in `tr///` [85107ec0] + + Fixed tap add/remove race in `Supplier` and `Supplier::Preserving` + [7ee1f3c5][68d79e70] + + `QuantHash`es now properly report `.of` and `.keyof` [8b93ec9f] + + Added type constraints to port numbers in `IO::Socket::Async` [547f28ba] + + Fixed re-initialization on some types of arrays [f1fa5adf] + [7262b4e8][49f07abe] + + Gave 6.d correct `is rw` Proxy semantics [7d37f9aa] + + Fixed `Match.^roles` [becbdeb9] + + Fixed missing path volume after `..` is resolved [8854bbd3] + + The `.values` method can now be used to change values in + object hashes [a728bb2d] + + Fixed shaped dynamic variables like `my %*a{Int}` [bcdf87a6] + + Made `my @a is Blob / Buf = ...` work [762c708f] + + Object hashes and `QuantHash`es can now be used with + metaops [Hyper refactor] + + Many improvements to the JS backend [32b7c089][f35dd301][9457f7e5] + [ea69c0a0][0e4969fe][9df074ba][78389aa2][1ef62aca][f460ad1a][cbbe16ed] + + Improved error message when using placeholders with methods [deae5bcd] + [0896c301][48093d0d][0bda7dc1][90103f6d][68b44e33][8549c4c1] + + Various improvements to produced messages [15c16e35][e6758492] + + Additions: + + Implemented `X::Language::TooLate` [3365094f] + + `$*COLLATION.set` is no longer experimental [20c41ca5] + + Added dynamic variable `$*FOLDING` [cec1f511] + + Removals: + + Removed unspecced `.allowed` attribute in `Pod::Block::Code` [5aba3e96] + + Set operators `(<+)`, `≼`, `(>+)`, `≽` now die when used [951303f9] + [7a1a1868][81474bf9][5598f37d] + + `Associative >>op<< Iterable` now dies, as the results are indeterminate + due to random hash key order [Hyper refactor] + + Build system: + + Fixed `t/*/*.t` rule in generated Makefile [d2c7e327] + + Made running timing based tests optional [72b896c8] + + Efficiency: + + Made `Int eqv Int` 3x and `int eqv int` 5x as fast [fb9a0454][94dd0a41] + + Made `ObjAt` `eqv` `ObjAt` also faster [5120d3d2] + + Made `Hash`/`Map` slices about 5x as fast [6fe27894][b83179f0] + [c4da4c7e][9a2c4b44] + + Optimized various operations on `Date` and `DateTime` making + them up to 3x as fast [11cb4fac][b6292fe9][08fac045][98d07cf6] + [b463746d][bf3eb8ec][a11d599f] + + Made metaops use the fast path for `&[+=]`-like ops [e7ce194a] + + Hyper operator refactor makes many things like + `%h >>+>> 1` 1.3x to 8x as fast [bfe2ad63][130cc817][0bc72e05] + [75c9456a][ec2848c4][f06e8582][73eb297f][194daab7][a575effe] + [c50cf82a][1a2b39dc][307a98bd][843118ea][6208c266][9221c08d] + [c03e71d5][78f64203][63ae9dcc][fa5215b6][d5a751d9][674a0837] + [8fa72681][80edefcf][cf5c8a09][534d8f65][7fad12b0][800d8fbb] + [c3f03e67][1ed2b098][21434dda][234e298b][e8285c01][32ab0d30] + [90ac0940][f7007ac0][dc67ee75][cae9847e][481dbf92][c4445649] + [19f0c842][86ce4f4e][50f2207b][2e5be5b8][1b7253df][64a47d87] + [005261a4][10693d16] + + Internal: + + Changed CORE.d setting compilation to propagate indicator flags [4a6d9108] + + Made sure we don't add object to serialization context more + than once [3995e423] + + New QAST to mbc compiler [edc4c054][6aafe18d][f8be2fa0][656a8045][bb43acdb] + + Added `Hash.STORE(\keys,\values)` [faa19ab9] + + Introduced `R:I.AssociativeIterableKeys` [6fe27894] + + Various internal optimizations [5f1a81e0][1766435a][8e858c8d][00eb7b85] + [0fa6988c][bf3575cc][18ded174] + + +The following people contributed to this release: + +Stefan Seifert, Elizabeth Mattijsen, Zoffix Znet, +Aleks-Daniel Jakimenko-Aleksejev, Paweł Murias, Timo Paulssen, Nick Logan, +Tom Browder, Rob Hoelz, Jonathan Worthington, Joelle Maslak, Donald Hunter, +Bart Wiegmans, Daniel Green, Fernando Correa de Oliveira, +Juan Julián Merelo Guervós, Samantha McVey + +If you would like to contribute or find out more information, visit +, , ask on the + mailing list, or ask on IRC #perl6 on freenode. + +Additionally, we invite you to make a donation to The Perl Foundation +to sponsor Perl 6 development: +(put “Perl 6 Core Development Fund” in the ‘Purpose’ text field) + +The next release of Rakudo (#129), is tentatively scheduled for 2018-12-15. + +A list of the other planned release dates is available in the +“docs/release_guide.pod” file. + +The development team appreciates feedback! If you’re using Rakudo, do +get back to us. Questions, comments, suggestions for improvements, cool +discoveries, incredible hacks, or any other feedback – get in touch with +us through (the above-mentioned) mailing list or IRC channel. Enjoy! + +Please note that recent releases have known issues running on the JVM. +We are working to get the JVM backend working again but do not yet have +an estimated delivery date. + +[^1]: See + +[^2]: What’s the difference between the Rakudo compiler and the Rakudo +Star distribution? + +The Rakudo compiler is a compiler for the Perl 6 language. +Not much more. + +The Rakudo Star distribution is the Rakudo compiler plus a selection +of useful Perl 6 modules, a module installer, Perl 6 introductory +documentation, and other software that can be used with the Rakudo +compiler to enhance its utility. diff -Nru rakudo-2018.10/docs/announce/2018.12.md rakudo-2018.12/docs/announce/2018.12.md --- rakudo-2018.10/docs/announce/2018.12.md 1970-01-01 00:00:00.000000000 +0000 +++ rakudo-2018.12/docs/announce/2018.12.md 2018-12-21 05:16:35.000000000 +0000 @@ -0,0 +1,105 @@ +# Announce: Rakudo Perl 6 compiler, Release #129 (2018.12) + +On behalf of the Rakudo development team, I’m very happy to announce the +December 2018 release of Rakudo Perl 6 #129. Rakudo is an implementation of +Perl 6 on the Moar Virtual Machine[^1]. + +This release implements 6.c and 6.d versions of the Perl 6 specification. +6.c version of the language is available if you use the `use v6.c` +version pragma, otherwise 6.d is the default. + +Upcoming releases in 2019 will include new functionality that is not +part of 6.c or 6.d specifications, available with a lexically scoped +pragma. Our goal is to ensure that anything that is tested as part of +6.c and 6.d specifications will continue to work unchanged. There may +be incremental spec releases this year as well. + +The tarball for this release is available from . + +Please note: This announcement is not for the Rakudo Star +distribution[^2] — it’s announcing a new release of the compiler +only. For the latest Rakudo Star release, see +. + +The changes in this release are outlined below: + +New in 2018.12: + + Fixes: + + Fixed infiniloops with some set operators [99d94db4][9f5cc8d1] + + Fixed regression in handling of `"1"..9` [d92b155c] + + Fixed use of `Proxy` in a class attribute using + the `Attribute`.`get_value`/`set_value` interface [a5411e45] + + Fixed semantics of `minpairs`/`maxpairs` (ignore undefined values) [7bf7a2c6] + + Fixed error on `@a > 2` if `@a` is a native array + + Fixed error reporting on initializing shaped array with + improperly shaped data [fd216fec] + + Negative indexes on native arrays are now checked properly [dd2af90c] + + Fixed use of uninitialized value in `IO::Notification` [83d0056b] + + Enums can now have private methods mixed in [3c2cfb22] + + Fixed resource content lookup for `Distribution::Path` [370310b3] + + Fixed precompilation when cwd gets changed at run time [e2e5cc53] + + Shared library versions are now ignored on OpenBSD [5603128e] + + Many improvements to the JS backend [1865db0d][fdd249a3][194c84b9] + [1dd59f10][52c2af5d][8b13655c][2869a48b][cf5432ae][758caa89] + [e0b943d0][a759f9d7] + + Various improvements to produced messages [869b9e58][abfb9a40] + [79824db5][55d08c8f][24c8e172] + + Additions: + + Added `Endian` enum and implemented new methods in `blob8`/`buf8` + for reading/writing native values [46d4c9fe][011c6f11][f66861dc] + [f0279313][b781f8cc][543219c9][77182713][06156a7c] + + Added `Kernel.endian` [2a761ca7][af43b159] + + Implemented `Blob.readint` / `Buf.writeint` [4f14d713][fecfb22d] + [5cc0e02d][79dd1c8e][ceaf7218][631940c7][38afa2d6][e7b61aff] + + Added `.native-descriptor` for async sockets [a4db9139][2fd90b1e] + + Added `.Real` method to native arrays [dd3f91a2] + + Implemented `last` and `LAST` in `whenever` blocks [890d628a] + + Efficiency: + + Made `<$rx>` interpolation 1.05x as fast [62243cd9] + + Made simple regex matches 1.05x as fast [01c56b48] + + Other minor optimizations [93ea7ed1][a0cb89a7][adb85609][6c2f3c83] + + Internal: + + Introduced a more generally usable `X::ArrayShapeMismatch` error [dd030145] + + Internal micro-optimizations [38bc682b][f18432ea] + + +The following people contributed to this release: + +Paweł Murias, Elizabeth Mattijsen, Aleks-Daniel Jakimenko-Aleksejev, +Stefan Seifert, Jonathan Worthington, Ben Davies, Petr Rockai, Nick Logan, +Samantha McVey, Timo Paulssen, Momo + +If you would like to contribute or find out more information, visit +, , ask on the + mailing list, or ask on IRC #perl6 on freenode. + +Additionally, we invite you to make a donation to The Perl Foundation +to sponsor Perl 6 development: +(put “Perl 6 Core Development Fund” in the ‘Purpose’ text field) + +The next release of Rakudo (#130), is tentatively scheduled for 2019-01-19. + +A list of the other planned release dates is available in the +“docs/release_guide.pod” file. + +The development team appreciates feedback! If you’re using Rakudo, do +get back to us. Questions, comments, suggestions for improvements, cool +discoveries, incredible hacks, or any other feedback – get in touch with +us through (the above-mentioned) mailing list or IRC channel. Enjoy! + +Please note that recent releases have known issues running on the JVM. +We are working to get the JVM backend working again but do not yet have +an estimated delivery date. + +[^1]: See + +[^2]: What’s the difference between the Rakudo compiler and the Rakudo +Star distribution? + +The Rakudo compiler is a compiler for the Perl 6 language. +Not much more. + +The Rakudo Star distribution is the Rakudo compiler plus a selection +of useful Perl 6 modules, a module installer, Perl 6 introductory +documentation, and other software that can be used with the Rakudo +compiler to enhance its utility. diff -Nru rakudo-2018.10/docs/ChangeLog rakudo-2018.12/docs/ChangeLog --- rakudo-2018.10/docs/ChangeLog 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/docs/ChangeLog 2018-12-21 05:16:35.000000000 +0000 @@ -1,3 +1,117 @@ +New in 2018.12: + + Fixes: + + Fixed infiniloops with some set operators [99d94db4][9f5cc8d1] + + Fixed regression in handling of `"1"..9` [d92b155c] + + Fixed use of `Proxy` in a class attribute using + the `Attribute`.`get_value`/`set_value` interface [a5411e45] + + Fixed semantics of `minpairs`/`maxpairs` (ignore undefined values) [7bf7a2c6] + + Fixed error on `@a > 2` if `@a` is a native array + + Fixed error reporting on initializing shaped array with + improperly shaped data [fd216fec] + + Negative indexes on native arrays are now checked properly [dd2af90c] + + Fixed use of uninitialized value in `IO::Notification` [83d0056b] + + Enums can now have private methods mixed in [3c2cfb22] + + Fixed resource content lookup for `Distribution::Path` [370310b3] + + Fixed precompilation when cwd gets changed at run time [e2e5cc53] + + Shared library versions are now ignored on OpenBSD [5603128e] + + Many improvements to the JS backend [1865db0d][fdd249a3][194c84b9] + [1dd59f10][52c2af5d][8b13655c][2869a48b][cf5432ae][758caa89] + [e0b943d0][a759f9d7] + + Various improvements to produced messages [869b9e58][abfb9a40] + [79824db5][55d08c8f][24c8e172] + + Additions: + + Added `Endian` enum and implemented new methods in `blob8`/`buf8` + for reading/writing native values [46d4c9fe][011c6f11][f66861dc] + [f0279313][b781f8cc][543219c9][77182713][06156a7c] + + Added `Kernel.endian` [2a761ca7][af43b159] + + Implemented `Blob.readint` / `Buf.writeint` [4f14d713][fecfb22d] + [5cc0e02d][79dd1c8e][ceaf7218][631940c7][38afa2d6][e7b61aff] + + Added `.native-descriptor` for async sockets [a4db9139][2fd90b1e] + + Added `.Real` method to native arrays [dd3f91a2] + + Implemented `last` and `LAST` in `whenever` blocks [890d628a] + + Efficiency: + + Made `<$rx>` interpolation 1.05x as fast [62243cd9] + + Made simple regex matches 1.05x as fast [01c56b48] + + Other minor optimizations [93ea7ed1][a0cb89a7][adb85609][6c2f3c83] + + Internal: + + Introduced a more generally usable `X::ArrayShapeMismatch` error [dd030145] + + Internal micro-optimizations [38bc682b][f18432ea] + +New in 2018.11: + + SPECIAL NOTES: + + 🎆❇️🔥 Default language version is now `v6.d` 🔥❇️🎆 [46ef0ea0] + + Deprecations: + + Deprecated `.path`/`.args` in `Proc::Async`, use `.command` + instead [45bbc946] + + Fixes: + + Fixed `$*PERL.version` to always report the right version [c9ecfb7a] + + Consistified `:U.pairup` with `:D.pairup` to return a Seq [d73272e4] + + Provided a stable `.WHICH` for `Map` [4e0a1c24][052067fd] + + Made sure `DEPRECATED` reports location correctly when + using `:up` [8561d0ae] + + Fixed literal `\` in `tr///` [85107ec0] + + Fixed tap add/remove race in `Supplier` and `Supplier::Preserving` + [7ee1f3c5][68d79e70] + + `QuantHash`es now properly report `.of` and `.keyof` [8b93ec9f] + + Added type constraints to port numbers in `IO::Socket::Async` [547f28ba] + + Fixed re-initialization on some types of arrays [f1fa5adf] + [7262b4e8][49f07abe] + + Gave 6.d correct `is rw` Proxy semantics [7d37f9aa] + + Fixed `Match.^roles` [becbdeb9] + + Fixed missing path volume after `..` is resolved [8854bbd3] + + The `.values` method can now be used to change values in + object hashes [a728bb2d] + + Fixed shaped dynamic variables like `my %*a{Int}` [bcdf87a6] + + Made `my @a is Blob / Buf = ...` work [762c708f] + + Object hashes and `QuantHash`es can now be used with + metaops [Hyper refactor] + + Many improvements to the JS backend [32b7c089][f35dd301][9457f7e5] + [ea69c0a0][0e4969fe][9df074ba][78389aa2][1ef62aca][f460ad1a][cbbe16ed] + + Improved error message when using placeholders with methods [deae5bcd] + [0896c301][48093d0d][0bda7dc1][90103f6d][68b44e33][8549c4c1] + + Various improvements to produced messages [15c16e35][e6758492] + + Additions: + + Implemented `X::Language::TooLate` [3365094f] + + `$*COLLATION.set` is no longer experimental [20c41ca5] + + Added dynamic variable `$*FOLDING` [cec1f511] + + Removals: + + Removed unspecced `.allowed` attribute in `Pod::Block::Code` [5aba3e96] + + Set operators `(<+)`, `≼`, `(>+)`, `≽` now die when used [951303f9] + [7a1a1868][81474bf9][5598f37d] + + `Associative >>op<< Iterable` now dies, as the results are indeterminate + due to random hash key order [Hyper refactor] + + Build system: + + Fixed `t/*/*.t` rule in generated Makefile [d2c7e327] + + Made running timing based tests optional [72b896c8] + + Efficiency: + + Made `Int eqv Int` 3x and `int eqv int` 5x as fast [fb9a0454][94dd0a41] + + Made `ObjAt` `eqv` `ObjAt` also faster [5120d3d2] + + Made `Hash`/`Map` slices about 5x as fast [6fe27894][b83179f0] + [c4da4c7e][9a2c4b44] + + Optimized various operations on `Date` and `DateTime` making + them up to 3x as fast [11cb4fac][b6292fe9][08fac045][98d07cf6] + [b463746d][bf3eb8ec][a11d599f] + + Made metaops use the fast path for `&[+=]`-like ops [e7ce194a] + + Hyper operator refactor makes many things like + `%h >>+>> 1` 1.3x to 8x as fast [bfe2ad63][130cc817][0bc72e05] + [75c9456a][ec2848c4][f06e8582][73eb297f][194daab7][a575effe] + [c50cf82a][1a2b39dc][307a98bd][843118ea][6208c266][9221c08d] + [c03e71d5][78f64203][63ae9dcc][fa5215b6][d5a751d9][674a0837] + [8fa72681][80edefcf][cf5c8a09][534d8f65][7fad12b0][800d8fbb] + [c3f03e67][1ed2b098][21434dda][234e298b][e8285c01][32ab0d30] + [90ac0940][f7007ac0][dc67ee75][cae9847e][481dbf92][c4445649] + [19f0c842][86ce4f4e][50f2207b][2e5be5b8][1b7253df][64a47d87] + [005261a4][10693d16] + + Internal: + + Changed CORE.d setting compilation to propagate indicator flags [4a6d9108] + + Made sure we don't add object to serialization context more + than once [3995e423] + + New QAST to mbc compiler [edc4c054][6aafe18d][f8be2fa0][656a8045][bb43acdb] + + Added `Hash.STORE(\keys,\values)` [faa19ab9] + + Introduced `R:I.AssociativeIterableKeys` [6fe27894] + + Various internal optimizations [5f1a81e0][1766435a][8e858c8d][00eb7b85] + [0fa6988c][bf3575cc][18ded174] + New in 2018.10: + SPECIAL NOTES: + This is the first Rakudo release that comes with an additional @@ -18,7 +132,7 @@ + Fixed indexing of shaped arrays with a dimension higher than 3 [0307c366] + `.in-timezone`s value is now coerced to Int [c8438e6a] + Stub methods from roles are now verified [fd5d5bdf] - + Fixed double-closing of handles in `.lines` when `:close` and + + Fixed double-closing of handles in `IO::Handle.lines` when `:close` and `$limit` are used [6edb142f] + Fixed closing of handles in `IO::Handle.lines` when `$limit` is used [c1c75740] @@ -62,14 +176,14 @@ + Other minor optimizations [464a86b1][ab83b9d8][8cc3d5d7][b107cda5] + Internal: + Made `make` an only [369068ae] - + Added skip-one method to appropriate PredictiveIterators [e54885e5] + + Added skip-one method to appropriate `PredictiveIterator`s [e54885e5] + More things are now initialized at setting compile time [06dfbf02][688cbac1][92735770] + Simplified initialization of `CompUnit::RepositoryRegistry` [0425d927][8e1cd01a] + Introduced `IterationBuffer.List` [8c10da6a] - + Made it not go through `.new` if we can `nqp::create` [84311b77] - + Made sure `.STORE` only works on instances [9daac683] + + Use `nqp::create` for IterationBuffer instead of .new [84311b77] + + Made sure `.STORE` only works on instances of mixy/baggy types [9daac683] + Added `$*INSIDE-EVAL` to mark that we're inside an `EVAL` [73b7c603] New in 2018.09: diff -Nru rakudo-2018.10/docs/rakudo-nqp-and-pod-notes.md rakudo-2018.12/docs/rakudo-nqp-and-pod-notes.md --- rakudo-2018.10/docs/rakudo-nqp-and-pod-notes.md 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/docs/rakudo-nqp-and-pod-notes.md 2018-12-21 05:16:35.000000000 +0000 @@ -2,26 +2,38 @@ ## Traps for the Perl 6 programmer -+ **DO NOT use '$0' in match results** - The Perl 6 shorthand for a match variable '**$0**' doesn't - work in NQP. Instead, use **$/[0]** for the zeroeth match. - Note the parser will be very confused otherwise and it currently cannot point to the error. - - -+ **DO NOT use 'nqp::say'** - The routine '**say**' is an NQP built-in and it does not need - the '**nqp::**' prefix. You can sometimes get away with using '**nqp::say**' but, when you least - expect it, the parser will fail without a helpful error message. - -+ **DO use 'nqp::die'** - As opposed to '**say**', '**die**' does need to be qualified with '**nqp::**'. - If used without the '**nqp::**' prefix, you sometimes may get a very unhelpful error message. - -+ **DO NOT use '$\' inside a sub with a '$/' arg** - Use the full syntax for - a match variable ('**/$' inside a sub with a '$/' + arg** - Use the full syntax for a match variable + ('**/$' versus + '$\\*\*1'** - The first form will result in a scalar + object while the '\*\*' form will result in an array. Either form + may be appropriate for the situation, but proper handling will vary + for each. + ++ **BE WARNED about "return if (...)" statements** - Sometimes they + work and sometimes not. But the failure message is usually good + enough to find the offending code. + For example, all these failed: - + ``` return if !nqp::elems(@arr); return unless nqp::elems(@arr); @@ -33,29 +45,43 @@ return; } ``` - + +## Pod compilation overview + +Pod is parsed as it is discovered during the parsing phase of each +compilation unit. Each pod object (string, paragraph, block, +configuration, term, heading, item, etc.) is serialized as it is +completed, and that result is a QAST node. The appropriate assembly of +QAST nodes (which have also been marked as a *compile_time_constant*) +are grouped into instances of pod classes as defined in +**src/core/Pod.pm6**. + ## Pod block text content handling -Text inside pod blocks that are contents rather than markup is comprised of -intermixed text and formatting code characters. Newlines and contiguous -whitespace may or may not be significant depending upon the general block type -(abbreviated, paragraph, delimited, or declarator) or block identifier (e.g., -code, input, output, defn, comment, or data). - -The content as it is parsed in Grammar.nqp is first broken into individual -characters which are then assigned to one of three token groups: regular text, text with -formatting code, and text that is to be unchanged from its input form -(code, input, and output). - -The regular text and intermingled formatted text are then divided into two more -categories: text that will form one or more paragraphs and text that is part -of a table. Ultimately, each paragraph of text should be grouped into the -@contents array of a single Pod::Block::Para, but not all pod handling per S26 -has been fully implemented. +Text inside pod blocks that are contents rather than markup is +comprised of intermixed text and formatting code characters. Newlines +and contiguous whitespace may or may not be significant depending upon +the general block type (abbreviated, paragraph, delimited, or +declarator) or block identifier (e.g., *code*, *input*, *output*, +*defn*, *comment*, or *data*). + +The content as it is parsed in Grammar.nqp is first broken into +individual characters which are then assigned to one of three token +groups: regular text, text with formatting code, and text that is to +be unchanged from its input form (*code*, *input*, and *output*). + +The regular text and intermingled formatted text are then divided into +two more categories: text that will form one or more paragraphs and +text that is part of a table. Ultimately, each paragraph of text +should be grouped into the @contents array of a single +**Pod::Block::Para**, but not all pod handling per S26 has been fully +implemented. -Some notable, not-yet-implemented (NYI) features (in order of one dev's TODO list) +Some notable, not-yet-implemented (NYI) features (in order of one +dev's TODO list) -1. NYI: %config :numbered aliasing with '#' for paragraph or delimited blocks +1. NYI: %config :numbered aliasing with '#' for paragraph or delimited + blocks 2. NYI: pod data blocks @@ -65,7 +91,7 @@ 5. NYI: pod configuration aliasing -6. NYI: formatting code in declarator blocks +6. NYI: formatting code in declarator blocks (not described in S26, but a user-requested feature) 7. NYI: consistent use of the Pod::Block::Para as the leaf parent of all regular text @@ -75,47 +101,107 @@ 10. NYI: nested delimited comment blocks -11. NYI: configuration data on continuation lines are not always handled correctly +11. NYI: configuration data on continuation lines are not always + handled correctly + +Anyone wanting to work on any of the NYI items please coordinate on +IRC #perl6-dev to avoid duplicate efforts. Most of the items are +being worked on in a generally logical order of need and knowledge +gained during the process of implementing pod features. + +## Pod nesting + +Complicating work with pod is that pod blocks can be nested, i.e., a +pod block can have pod blocks as children, to any depth. Necessarily +that applies, in general, to *delimited blocks*. (Other block types +may have single blocks as children, usually as one or two +**Pod::Block::Paras**.) + +One consequence of this is that a pod block with children cannot be +created until all its children have been created. Another consequence +is that a pod block can have several parts, some of which cannot be +created until child components are analyzed or created. + +## Pod block parts + +A pod block can have several parts, all of which must be created +before the block itself can be created. Those parts are: + +* Configuration - `%.config` [all blocks inheriting from class **Pod::Block**] + + * The configuration cannot be created until the block text data are analyzed. + + * Note that *abbreviated* blocks cannot have an explicit configuration +section, but they may have limited implicit configuration data through +use of *:numbered aliasing* (see below). + +* Contents - `@.contents` [all blocks inheriting from class **Pod::Block**] + + * The contents cannot be created until all child blocks are created. + +* Term - `$.term` [*defn* blocks] + + * The term cannot be created until the block text data are analyzed. + +* Caption - `$.caption` [*table* blocks] + + * The caption cannot be created until the configuration is analyzed. + +* Headers - `@.headers` [*table* blocks] -Anyone wanting to work on any of the NYI items please coordinate on IRC #perl6-dev to -avoid duplicate efforts. Most of the items are being worked on in a generally logical -order of need and knowledge gained during the process of implementing pod features. + * The headers cannot be created until the block text data are analyzed. ## The token -The token **pod_textcontent** is the match object for regular text and formatted code as -described above. It is the source of the final contents object for regular text containers -except for the table blocks which will be discussed separately. It has a corresponding action -method. - -Tracing the pod class building code is tedious and not well documented. Tokens in the grammar -are often made early, along with other objects, and attached to that token's match object's .ast -attribute which is then used later in another object. The developer who wants to change the called .ast -code in that other object (which may be in the grammar, actions, or src/Perl6/Pod.nqp) has to refer -back to the original make point to see its format before doing any changes--not fun! -There is an ongoing effort to better document the process for later developers. - -Following is the start of a table to show the grammar tokens that have action methods. - -| Grammar tokens | Action method? | Pod sub? | -| --- | --- | --- | -| pod_textcontent | yes +The token **pod_textcontent** is the match object for regular text and +formatted code as described above. It is the source of the final +contents object for regular text containers except for the table +blocks which will be discussed separately. It has a corresponding +action method. + +Tracing the pod class building code is tedious and not well +documented. Tokens in the grammar are often made early, along with +other objects, and attached to that token's match object's .ast +attribute which is then used later in another object. The developer +who wants to change the called .ast code in that other object (which +may be in the grammar, actions, or src/Perl6/Pod.nqp) has to refer +back to the original make point to see its format before doing any +changes--not fun! There is an ongoing effort to better document the +process for later developers. + +Following is the start of a table to show the grammar tokens that have +action methods and their resulting `.ast` values. + +| Actions method | `made` (`ast`) value +| --- | --- +| pod_textcontent | +| pod_block:sym\ | QAST node [instance of Pod::Heading] +| pod_block:sym\ | QAST node [instance of Pod::Item] +| pod_block:sym\ | QAST node [instance of Pod::Defn] +| pod_block:sym\ | QAST node [instance of Pod::Block::Named] +| pod_content:sym\ | $.ast; +| pod_content_toplevel | $.ast ## :numbered aliasing -S26 allows for the '#' character (Unicode name **NUMBER SIGN**), as the first word in a block, -to turn on the **:numbered** %config key; in that case the '#' will be removed from the data. -The user can allow a '#' to be recognized as data by either (1) setting the %config numbered -key to false, typically with the **:!numbered** form, or (2) using the **V** formatting code -around the '#' in the data like this: **V<#>**. - -Proper handling of this feature requires changing the block's %config hash after the block data have been -parsed or possibly changing the parsing of the first block data word due to the presence of **:!numbered** in -the %config hash. Another problem is how to handle duplicate or incompatible %config keys and values. - -The easiest case to handle is the abbreviated block which cannot have explicit %config data and for -which the :numbered alias is most useful. Examples of the abbreviated blocks most likely to -use this option are the **=item**, **=head**, and **=defn** types. +S26 allows for the '#' character (Unicode name **NUMBER SIGN**), as +the first word in a block, to turn on the **:numbered** %config key; +in that case the '#' will be removed from the data. The user can +allow a '#' to be recognized as data by either (1) setting the %config +numbered key to false, typically with the **:!numbered** form, or (2) +using the **V** formatting code around the '#' in the data like this: +**V<#>**. + +Proper handling of this feature requires changing the block's %config +hash after the block data have been parsed or possibly changing the +parsing of the first block data word due to the presence of +**:!numbered** in the %config hash. Another problem is how to handle +duplicate or incompatible %config keys and values. + +The easiest case to handle is the abbreviated block which cannot have +explicit %config data and for which the :numbered alias is most +useful. Examples of the abbreviated blocks most likely to use this +option are the **=item**, **=head**, and **=defn** types. The '#' turns on the **:numbered** configuration in all these cases: @@ -138,12 +224,14 @@ # foo bar ``` -The **:!numbered** is interpreted to mean accepting the '#' as part of block data. +The **:!numbered** is interpreted to mean accepting the '#' as part of +block data. ``` =for para :numbered # foo bar ``` -The '#' means the same as the **:numbered** option: the renderer should number the -paragraph and the two **:numbered** keys (one explict and one implicit) are redundant. +The '#' means the same as the **:numbered** option: the renderer +should number the paragraph and the two **:numbered** keys (one +explict and one implicit) are redundant. diff -Nru rakudo-2018.10/docs/release_guide.pod rakudo-2018.12/docs/release_guide.pod --- rakudo-2018.10/docs/release_guide.pod 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/docs/release_guide.pod 2018-12-21 05:16:35.000000000 +0000 @@ -18,8 +18,18 @@ compatibility issues post Christmas. As such, we may end up delaying some releases to ensure any compatibility issues are resolved. - 2018-11-17 Rakudo #128 (AlexDaniel + Releasable) - 2018-12-15 Rakudo #129 + 2019-01-19 Rakudo #130 + 2019-02-16 Rakudo #131 + 2019-03-16 Rakudo #132 + 2019-04-20 Rakudo #133 + 2019-05-18 Rakudo #134 + 2019-06-15 Rakudo #135 + 2019-07-20 Rakudo #136 + 2019-08-17 Rakudo #137 + 2019-09-21 Rakudo #138 + 2019-10-19 Rakudo #139 + 2019-11-16 Rakudo #140 + 2019-12-21 Rakudo #141 (More planned dates can be generated with F). @@ -258,7 +268,9 @@ (cd t/spec && git checkout master) # test latest language spec make stresstest - (cd t/spec && git checkout 6.c-errata) # test stable language spec + (cd t/spec && git checkout 6.c-errata) # test stable language spec (6.c) + make stresstest + (cd t/spec && git checkout 6.d-errata) # test stable language spec (6.d) make stresstest There are many tests to run for the stresstest target. If @@ -495,6 +507,8 @@ 2018-09-02 Rakudo #125 "2018.08" (AlexDaniel + Releasable) 2018-09-23 Rakudo #126 "2018.09" (AlexDaniel + Releasable) 2018-10-28 Rakudo #127 "2018.10" (AlexDaniel + Releasable) + 2018-11-29 Rakudo #128 "2018.11" (AlexDaniel + Releasable) # v6.d + 2018-12-21 Rakudo #129 "2018.12" (AlexDaniel + Releasable) =head1 COPYRIGHT diff -Nru rakudo-2018.10/lib/experimental.pm6 rakudo-2018.12/lib/experimental.pm6 --- rakudo-2018.10/lib/experimental.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/lib/experimental.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -193,7 +193,12 @@ } package EXPORT::collation { - OUR:: := True; + # this is no longer experimental, but keep the package to prevent + # code that caters to this and earlier versions of compilers from + # breaking + # + # XXX TODO: should be fine to remove on 2019-12. There is also a test + # in t/02-rakudo/99-misc.t that will need to be removed too at the time } # vim: ft=perl6 expandtab sw=4 diff -Nru rakudo-2018.10/lib/Pod/To/Text.pm6 rakudo-2018.12/lib/Pod/To/Text.pm6 --- rakudo-2018.10/lib/Pod/To/Text.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/lib/Pod/To/Text.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -12,18 +12,21 @@ sub pod2text($pod) is export { given $pod { - when Pod::Heading { heading2text($pod) } - when Pod::Block::Code { code2text($pod) } - when Pod::Block::Named { named2text($pod) } - when Pod::Block::Para { twrap( $pod.contents.map({pod2text($_)}).join("") ) } - when Pod::Block::Table { table2text($pod) } - when Pod::Block::Declarator { declarator2text($pod) } - when Pod::Item { item2text($pod).indent(2) } - when Pod::FormattingCode { formatting2text($pod) } - when Positional { .flat».&pod2text.grep(?*).join: "\n\n" } - when Pod::Block::Comment { '' } - when Pod::Config { '' } - default { $pod.Str } + when Pod::Heading { heading2text($pod) } + when Pod::Block::Code { code2text($pod) } + when Pod::Block::Named { named2text($pod) } + when Pod::Block::Para { twrap( $pod.contents.map({pod2text($_)}).join("") ) } + when Pod::Block::Table { table2text($pod) } + when Pod::Block::Declarator { declarator2text($pod) } + when Pod::Item { item2text($pod).indent(2) } + when Pod::Defn { pod2text($pod.contents[0]) ~ "\n" + ~ pod2text($pod.contents[1..*-1]) } + + when Pod::FormattingCode { formatting2text($pod) } + when Positional { .flat».&pod2text.grep(?*).join: "\n\n" } + when Pod::Block::Comment { '' } + when Pod::Config { '' } + default { $pod.Str } } } @@ -47,8 +50,6 @@ given $pod.name { when 'pod' { pod2text($pod.contents) } when 'para' { para2text($pod.contents[0]) } - when 'defn' { pod2text($pod.contents[0]) ~ "\n" - ~ pod2text($pod.contents[1..*-1]) } when 'config' { } when 'nested' { } default { $pod.name ~ "\n" ~ pod2text($pod.contents) } diff -Nru rakudo-2018.10/MANIFEST rakudo-2018.12/MANIFEST --- rakudo-2018.10/MANIFEST 2018-10-28 22:28:05.000000000 +0000 +++ rakudo-2018.12/MANIFEST 2018-12-21 06:10:14.000000000 +0000 @@ -127,6 +127,8 @@ docs/announce/2018.08.md docs/announce/2018.09.md docs/announce/2018.10.md +docs/announce/2018.11.md +docs/announce/2018.12.md docs/architecture.html docs/architecture.svg docs/archive/2017-IO-Grant--Action-Plan.md @@ -255,6 +257,7 @@ src/core/Hash.pm6 src/core/hash_slice.pm6 src/core/HyperConfiguration.pm6 +src/core/Hyper.pm6 src/core/HyperSeq.pm6 src/core/Instant.pm6 src/core/Int.pm6 @@ -451,6 +454,8 @@ src/Perl6/Pod.nqp src/Perl6/World.nqp src/RESTRICTED.setting +src/vm/js/CompUnit/Repository/FileSystemWithRecording.pm6 +src/vm/js/load-compiler.nqp src/vm/js/make-release.js src/vm/js/ModuleLoaderVMConfig.nqp src/vm/js/Perl6/Ops.nqp @@ -643,6 +648,17 @@ tools/util/perlcritic.conf t/packages/Test/Helpers.pm6 t/packages/Test/Helpers/QAST.pm6 +t/spec/3rdparty/Unicode/11.0.0/ucd/auxiliary/GraphemeBreakTest.txt +t/spec/3rdparty/Unicode/LICENSE +t/spec/3rdparty/wikipedia/Arabic.txt +t/spec/3rdparty/wikipedia/Hangul.txt +t/spec/3rdparty/wikipedia/LICENSE +t/spec/3rdparty/wikipedia/Tibetan.txt +t/spec/CONTRIBUTING.md +t/spec/docs/announce/6.d.md +t/spec/docs/New-Features-Policy.md +t/spec/docs/release-guide.md +t/spec/docs/unicode-generated-tests.asciidoc t/spec/fudge t/spec/fudgeall t/spec/fudgeandrun @@ -741,7 +757,10 @@ t/spec/integration/advent2014-day13.t t/spec/integration/advent2014-day16.t t/spec/integration/code-blocks-as-sub-args.t +t/spec/integration/deep-recursion-initing-native-array.t t/spec/integration/error-reporting.t +t/spec/integration/eval-and-threads.t +t/spec/integration/failure-and-callsame.t t/spec/integration/lazy-bentley-generator.t t/spec/integration/lexical-array-in-inner-block.t t/spec/integration/lexicals-and-attributes.t @@ -761,103 +780,151 @@ t/spec/integration/variables-in-do.t t/spec/integration/weird-errors.t t/spec/LICENSE -t/spec/packages/A/A.pm -t/spec/packages/A/B.pm -t/spec/packages/Advent/GrammarProfiler.pm -t/spec/packages/Advent/MetaBoundaryAspect.pm -t/spec/packages/Advent/SingleInheritance.pm -t/spec/packages/A.pm -t/spec/packages/ArrayInit.pm -t/spec/packages/Bar.pm -t/spec/packages/Baz.pm -t/spec/packages/B/Grammar.pm -t/spec/packages/B.pm -t/spec/packages/ContainsUnicode.pm -t/spec/packages/Example2/A.pm -t/spec/packages/Example2/B.pm -t/spec/packages/Example2/C.pm -t/spec/packages/Example2/D.pm -t/spec/packages/Example2/E.pm -t/spec/packages/Example2/F.pm -t/spec/packages/Example2/G.pm -t/spec/packages/Example2/H.pm -t/spec/packages/Example2/K.pm -t/spec/packages/Example2/N.pm -t/spec/packages/Example2/P.pm -t/spec/packages/Example2/R.pm -t/spec/packages/Example2/S.pm -t/spec/packages/Example2/T.pm -t/spec/packages/Example2/U.pm -t/spec/packages/Example/A.pm -t/spec/packages/Example/B.pm -t/spec/packages/Example/C.pm -t/spec/packages/Exportops.pm -t/spec/packages/Export_PackA.pm -t/spec/packages/Export_PackB.pm -t/spec/packages/Export_PackC.pm -t/spec/packages/Export_PackD.pm -t/spec/packages/Fancy/Utilities.pm -t/spec/packages/FooBar.pm -t/spec/packages/Foo.pm -t/spec/packages/HasMain.pm -t/spec/packages/Import.pm -t/spec/packages/LoadCounter.pm -t/spec/packages/LoadFromInsideAClass.pm -t/spec/packages/LoadFromInsideAModule.pm -t/spec/packages/OverrideTest.pm -t/spec/packages/PackageTest.pm +t/spec/MISC/bug-coverage-6.d.t +t/spec/MISC/bug-coverage-stress-6.d.t +t/spec/MISC/bug-coverage-stress.t +t/spec/MISC/bug-coverage.t +t/spec/MISC/misc-6.d.t +t/spec/packages/A/A.pm6 +t/spec/packages/A/B.pm6 +t/spec/packages/Advent/GrammarProfiler.pm6 +t/spec/packages/Advent/MetaBoundaryAspect.pm6 +t/spec/packages/Advent/SingleInheritance.pm6 +t/spec/packages/A.pm6 +t/spec/packages/ArrayInit.pm6 +t/spec/packages/Bar.pm6 +t/spec/packages/Baz.pm6 +t/spec/packages/B/Grammar.pm6 +t/spec/packages/B.pm6 +t/spec/packages/ContainsUnicode.pm6 +t/spec/packages/Example2/A.pm6 +t/spec/packages/Example2/B.pm6 +t/spec/packages/Example2/C.pm6 +t/spec/packages/Example2/D.pm6 +t/spec/packages/Example2/E.pm6 +t/spec/packages/Example2/F.pm6 +t/spec/packages/Example2/G.pm6 +t/spec/packages/Example2/H.pm6 +t/spec/packages/Example2/K.pm6 +t/spec/packages/Example2/N.pm6 +t/spec/packages/Example2/P.pm6 +t/spec/packages/Example2/R.pm6 +t/spec/packages/Example2/S.pm6 +t/spec/packages/Example2/T.pm6 +t/spec/packages/Example2/U.pm6 +t/spec/packages/Example/A.pm6 +t/spec/packages/Example/B.pm6 +t/spec/packages/Example/C.pm6 +t/spec/packages/ExportConstant.pm6 +t/spec/packages/Exportops.pm6 +t/spec/packages/Export_PackA.pm6 +t/spec/packages/Export_PackB.pm6 +t/spec/packages/Export_PackC.pm6 +t/spec/packages/Export_PackD.pm6 +t/spec/packages/Fancy/Utilities.pm6 +t/spec/packages/FooBar.pm6 +t/spec/packages/Foo.pm6 +t/spec/packages/HasMain.pm6 +t/spec/packages/Import.pm6 +t/spec/packages/InternArrayA.pm6 +t/spec/packages/InternArrayB.pm6 +t/spec/packages/LoadCounter.pm6 +t/spec/packages/LoadFromInsideAClass.pm6 +t/spec/packages/LoadFromInsideAModule.pm6 +t/spec/packages/OverrideTest.pm6 +t/spec/packages/PackageTest.pm6 t/spec/packages/PM6.pm6 +t/spec/packages/RAKUDO1413.pm6 t/spec/packages/README -t/spec/packages/RequireAndUse1.pm -t/spec/packages/RequireAndUse2.pm -t/spec/packages/RequireAndUse3.pm -t/spec/packages/RoleA.pm -t/spec/packages/RoleB.pm -t/spec/packages/RT115240.pm -t/spec/packages/RT122447.pm -t/spec/packages/RT123276/B/C1.pm -t/spec/packages/RT123276/B/C2.pm -t/spec/packages/RT123276.pm -t/spec/packages/RT124162.pm -t/spec/packages/RT125090.pm -t/spec/packages/RT125245.pm +t/spec/packages/RequireAndUse1.pm6 +t/spec/packages/RequireAndUse2.pm6 +t/spec/packages/RequireAndUse3.pm6 +t/spec/packages/RoleA.pm6 +t/spec/packages/RoleB.pm6 +t/spec/packages/RT112626/Class1.pm6 +t/spec/packages/RT112626/Class2.pm6 +t/spec/packages/RT112626/Conflict.pm6 +t/spec/packages/RT112626/Role.pm6 +t/spec/packages/RT115240.pm6 +t/spec/packages/RT117117/Backend/AST.pm6 +t/spec/packages/RT117117/Backend/GNUC.pm6 +t/spec/packages/RT117117/Backends.pm6 +t/spec/packages/RT117117/Grammar.pm6 +t/spec/packages/RT122447.pm6 +t/spec/packages/RT123276/B/C1.pm6 +t/spec/packages/RT123276/B/C2.pm6 +t/spec/packages/RT123276.pm6 +t/spec/packages/RT124162.pm6 +t/spec/packages/RT125090.pm6 +t/spec/packages/RT125245.pm6 t/spec/packages/RT125715.pm6 -t/spec/packages/RT126904/lib/Woohoo/Foo/Bar.pm -t/spec/packages/RT126904/lib/Woohoo/Foo/Baz.pm -t/spec/packages/RT126904/lib/Woohoo/Qux.pm -t/spec/packages/RT76456.pm -t/spec/packages/RT76606/a.pm -t/spec/packages/RT76606.pm -t/spec/packages/RT83354_A.pm -t/spec/packages/RT83354_B.pm -t/spec/packages/RT84280.pm -t/spec/packages/S11-modules/Foo.pm -t/spec/packages/Test/Assuming.pm -t/spec/packages/Test/Compile.pm -t/spec/packages/Test/Idempotence.pm -t/spec/packages/Test/Tap.pm -t/spec/packages/Test/Util.pm -t/spec/packages/UseTest.pm -t/spec/README +t/spec/packages/RT126302/B.pm6 +t/spec/packages/RT126302.pm6 +t/spec/packages/RT126878/NoPrecomp.pm6 +t/spec/packages/RT126878/Precomp.pm6 +t/spec/packages/RT126904/lib/Woohoo/Foo/Bar.pm6 +t/spec/packages/RT126904/lib/Woohoo/Foo/Baz.pm6 +t/spec/packages/RT126904/lib/Woohoo/Qux.pm6 +t/spec/packages/RT127176.pm6 +t/spec/packages/RT128156/A.pm6 +t/spec/packages/RT128156/B.pm6 +t/spec/packages/RT128156/C.pm6 +t/spec/packages/RT128156/D.pm6 +t/spec/packages/RT128156/Needed.pm6 +t/spec/packages/RT128156/One.pm6 +t/spec/packages/RT128156/Three.pm6 +t/spec/packages/RT128156/Top1.pm6 +t/spec/packages/RT128156/Top2.pm6 +t/spec/packages/RT128156/Two.pm6 +t/spec/packages/RT129215.pm6 +t/spec/packages/RT129266/Bar.pm6 +t/spec/packages/RT129266/Foo.pm6 +t/spec/packages/RT76456.pm6 +t/spec/packages/RT76606/a.pm6 +t/spec/packages/RT76606.pm6 +t/spec/packages/RT83354_A.pm6 +t/spec/packages/RT83354_B.pm6 +t/spec/packages/RT84280.pm6 +t/spec/packages/S11-modules/EmptyClass.pm6 +t/spec/packages/S11-modules/ExportsEnumDate.pm6 +t/spec/packages/S11-modules/Foo.pm6 +t/spec/packages/S11-modules/MainLoadsNestedFirst/Nested.pm6 +t/spec/packages/S11-modules/MainLoadsNestedFirst.pm6 +t/spec/packages/S11-modules/MainLoadsNestedInside/Nested.pm6 +t/spec/packages/S11-modules/MainLoadsNestedInside.pm6 +t/spec/packages/S11-modules/Main/Nested.pm6 +t/spec/packages/S11-modules/Main.pm6 +t/spec/packages/S11-modules/RuntimeCreatedPackage.pm6 +t/spec/packages/Test/Assuming.pm6 +t/spec/packages/Test/Compile.pm6 +t/spec/packages/Test/Idempotence.pm6 +t/spec/packages/Test/Iterator.pm6 +t/spec/packages/Test/Tap.pm6 +t/spec/packages/Test/Util.pm6 +t/spec/packages/UseTest.pm6 +t/spec/README.md t/spec/rosettacode/greatest_element_of_a_list.t t/spec/rosettacode/README t/spec/rosettacode/sierpinski_triangle.t t/spec/S01-perl-5-integration/array.t t/spec/S01-perl-5-integration/basic.t t/spec/S01-perl-5-integration/class.t +t/spec/S01-perl-5-integration/context.t +t/spec/S01-perl-5-integration/eval_lex.t t/spec/S01-perl-5-integration/exception_handling.t t/spec/S01-perl-5-integration/hash.t t/spec/S01-perl-5-integration/import.t t/spec/S01-perl-5-integration/method.t +t/spec/S01-perl-5-integration/modify_inside_p5_p6.t +t/spec/S01-perl-5-integration/modify_inside_p5.t t/spec/S01-perl-5-integration/README t/spec/S01-perl-5-integration/return.t t/spec/S01-perl-5-integration/roundtrip.t t/spec/S01-perl-5-integration/strings.t t/spec/S01-perl-5-integration/subs.t -t/spec/S02-lexical-conventions/begin_end_pod.t t/spec/S02-lexical-conventions/bom.t t/spec/S02-lexical-conventions/comments.t -t/spec/S02-lexical-conventions/end-pod.t +t/spec/S02-lexical-conventions/finish-pod.t t/spec/S02-lexical-conventions/minimal-whitespace.t t/spec/S02-lexical-conventions/one-pass-parsing.t t/spec/S02-lexical-conventions/pod-in-multi-line-exprs.t @@ -901,6 +968,7 @@ t/spec/S02-magicals/dollar-underscore.t t/spec/S02-magicals/env.t t/spec/S02-magicals/file_line.t +t/spec/S02-magicals/GROUP.t t/spec/S02-magicals/KERNEL.t t/spec/S02-magicals/PERL.t t/spec/S02-magicals/pid.t @@ -908,6 +976,7 @@ t/spec/S02-magicals/subname.t t/spec/S02-magicals/sub.t t/spec/S02-magicals/UsedEnv.pm6 +t/spec/S02-magicals/USER.t t/spec/S02-magicals/VM.t t/spec/S02-names/bare-sigil.t t/spec/S02-names/caller.t @@ -930,6 +999,7 @@ t/spec/S02-names-vars/variables-and-packages.t t/spec/S02-names-vars/varnames.t t/spec/S02-one-pass-parsing/less-than.t +t/spec/S02-one-pass-parsing/misc.t t/spec/S02-packages/package-lookup.t t/spec/S02-types/anon_block.t t/spec/S02-types/array_extending.t @@ -938,7 +1008,9 @@ t/spec/S02-types/array.t t/spec/S02-types/assigning-refs.t t/spec/S02-types/autovivification.t +t/spec/S02-types/baggy.t t/spec/S02-types/baghash.t +t/spec/S02-types/bag-iterator.t t/spec/S02-types/bag.t t/spec/S02-types/bool.t t/spec/S02-types/built-in.t @@ -950,6 +1022,7 @@ t/spec/S02-types/flattening.t t/spec/S02-types/hash_ref.t t/spec/S02-types/hash.t +t/spec/S02-types/hyperwhatever.t t/spec/S02-types/infinity.t t/spec/S02-types/instants-and-durations.t t/spec/S02-types/int-uint.t @@ -961,8 +1034,10 @@ t/spec/S02-types/list.t t/spec/S02-types/mixed_multi_dimensional.t t/spec/S02-types/mixhash.t +t/spec/S02-types/mix-iterator.t t/spec/S02-types/mix.t t/spec/S02-types/multi_dimensional_array.t +t/spec/S02-types/mu.t t/spec/S02-types/nan.t t/spec/S02-types/native.t t/spec/S02-types/nested_arrays.t @@ -971,9 +1046,11 @@ t/spec/S02-types/num.t t/spec/S02-types/pair.t t/spec/S02-types/parsing-bool.t +t/spec/S02-types/range-iterator.t t/spec/S02-types/range.t t/spec/S02-types/resolved-in-setting.t t/spec/S02-types/sethash.t +t/spec/S02-types/set-iterator.t t/spec/S02-types/set.t t/spec/S02-types/sigils-and-types.t t/spec/S02-types/stash.t @@ -982,6 +1059,7 @@ t/spec/S02-types/type.t t/spec/S02-types/undefined-types.t t/spec/S02-types/unicode.t +t/spec/S02-types/version-stress.t t/spec/S02-types/version.t t/spec/S02-types/whatever.t t/spec/S02-types/WHICH.t @@ -1000,6 +1078,7 @@ t/spec/S03-metaops/cross.t t/spec/S03-metaops/eager-hyper.t t/spec/S03-metaops/hyper.t +t/spec/S03-metaops/misc.t t/spec/S03-metaops/not.t t/spec/S03-metaops/reduce.t t/spec/S03-metaops/reverse.t @@ -1013,7 +1092,6 @@ t/spec/S03-operators/autoincrement-range.t t/spec/S03-operators/autoincrement.t t/spec/S03-operators/autovivification.t -t/spec/S03-operators/bag.t t/spec/S03-operators/basic-types.t t/spec/S03-operators/bit.t t/spec/S03-operators/boolean-bitwise.t @@ -1041,9 +1119,9 @@ t/spec/S03-operators/list-quote-junction.t t/spec/S03-operators/minmax.t t/spec/S03-operators/misc.t -t/spec/S03-operators/mix.t t/spec/S03-operators/names.t t/spec/S03-operators/nesting.t +t/spec/S03-operators/notandthen.t t/spec/S03-operators/not.t t/spec/S03-operators/numeric-shift.t t/spec/S03-operators/orelse.t @@ -1056,14 +1134,25 @@ t/spec/S03-operators/relational.t t/spec/S03-operators/repeat.t t/spec/S03-operators/scalar-assign.t -t/spec/S03-operators/set.t +t/spec/S03-operators/set_addition.t +t/spec/S03-operators/set_difference.t +t/spec/S03-operators/set_elem.t +t/spec/S03-operators/set_intersection.t +t/spec/S03-operators/set_multiply.t +t/spec/S03-operators/set_precedes.t +t/spec/S03-operators/set_proper_subset.t +t/spec/S03-operators/set_subset.t +t/spec/S03-operators/set_symmetric_difference.t +t/spec/S03-operators/set_union.t t/spec/S03-operators/short-circuit.t +t/spec/S03-operators/shortcuts.t t/spec/S03-operators/so.t t/spec/S03-operators/spaceship-and-containers.t t/spec/S03-operators/spaceship.t t/spec/S03-operators/subscript-adverbs.t t/spec/S03-operators/subscript-vs-lt.t t/spec/S03-operators/ternary.t +t/spec/S03-operators/u2212-minus.t t/spec/S03-operators/value_equivalence.t t/spec/S03-sequence/arity0.t t/spec/S03-sequence/arity-2-or-more.t @@ -1095,6 +1184,7 @@ t/spec/S04-blocks-and-statements/pointy-rw.t t/spec/S04-blocks-and-statements/pointy.t t/spec/S04-blocks-and-statements/temp.t +t/spec/S04-declarations/constant-6.d.t t/spec/S04-declarations/constant.t t/spec/S04-declarations/implicit-parameter.t t/spec/S04-declarations/multiple.t @@ -1107,6 +1197,7 @@ t/spec/S04-exception-handlers/control.t t/spec/S04-exception-handlers/top-level.t t/spec/S04-exceptions/control_across_runloop.t +t/spec/S04-exceptions/exceptions-alternatives.t t/spec/S04-exceptions/fail.t t/spec/S04-exceptions/pending.t t/spec/S04-phasers/ascending-order.t @@ -1115,11 +1206,12 @@ t/spec/S04-phasers/descending-order.t t/spec/S04-phasers/end.t t/spec/S04-phasers/enter-leave.t -t/spec/S04-phasers/eval-in-begin.t +t/spec/S04-phasers/exit-in-check.t t/spec/S04-phasers/first.t t/spec/S04-phasers/in-eval.t t/spec/S04-phasers/init.t t/spec/S04-phasers/in-loop.t +t/spec/S04-phasers/interpolate.t t/spec/S04-phasers/keep-undo.t t/spec/S04-phasers/multiple.t t/spec/S04-phasers/next.t @@ -1141,9 +1233,12 @@ t/spec/S04-statements/for_with_only_one_item.t t/spec/S04-statements/gather.t t/spec/S04-statements/given.t +t/spec/S04-statements/goto.t t/spec/S04-statements/if.t t/spec/S04-statements/label.t t/spec/S04-statements/last.t +t/spec/S04-statements/lazy.t +t/spec/S04-statements/leave.t t/spec/S04-statements/loop.t t/spec/S04-statements/map-and-sort-in-for.t t/spec/S04-statements/next.t @@ -1165,6 +1260,8 @@ t/spec/S05-capture/array-alias.t t/spec/S05-capture/caps.t t/spec/S05-capture/dot.t +t/spec/S05-capture/external-aliasing.t +t/spec/S05-capture/hash.t t/spec/S05-capture/match-object.t t/spec/S05-capture/named.t t/spec/S05-capture/subrule.t @@ -1184,6 +1281,7 @@ t/spec/S05-mass/charsets.t t/spec/S05-mass/named-chars.t t/spec/S05-mass/properties-block.t +t/spec/S05-mass/properties-contributory.t t/spec/S05-mass/properties-derived.t t/spec/S05-mass/properties-general.t t/spec/S05-mass/properties-script.t @@ -1221,6 +1319,7 @@ t/spec/S05-modifier/continue.t t/spec/S05-modifier/counted-match.t t/spec/S05-modifier/counted.t +t/spec/S05-modifier/exhaustive.t t/spec/S05-modifier/global.t t/spec/S05-modifier/ignorecase-and-ignoremark.t t/spec/S05-modifier/ignorecase.t @@ -1229,6 +1328,7 @@ t/spec/S05-modifier/my.t t/spec/S05-modifier/overlapping.t t/spec/S05-modifier/perl5_0.t +t/spec/S05-modifier/perl5_10.t t/spec/S05-modifier/perl5_1.t t/spec/S05-modifier/perl5_2.t t/spec/S05-modifier/perl5_3.t @@ -1239,19 +1339,27 @@ t/spec/S05-modifier/perl5_8.t t/spec/S05-modifier/perl5_9.t t/spec/S05-modifier/pos.t +t/spec/S05-modifier/ratchet.t t/spec/S05-modifier/repetition-exhaustive.t t/spec/S05-modifier/repetition.t +t/spec/S05-modifier/samemark.t t/spec/S05-modifier/sigspace.t +t/spec/S05-nonstrings/basic.t t/spec/S05-substitution/67222.t t/spec/S05-substitution/match.t t/spec/S05-substitution/subst.t +t/spec/S05-syntactic-categories/new-symbols.t t/spec/S05-transliteration/79778.t t/spec/S05-transliteration/trans.t +t/spec/S05-transliteration/trans-tr-lowercase-operator.t +t/spec/S05-transliteration/trans-TR-operator.t t/spec/S05-transliteration/with-closure.t +t/spec/S06-advanced/caller.t t/spec/S06-advanced/callframe.t t/spec/S06-advanced/callsame.t t/spec/S06-advanced/lexical-subs.t t/spec/S06-advanced/recurse.t +t/spec/S06-advanced/return_function.t t/spec/S06-advanced/return.t t/spec/S06-advanced/stub.t t/spec/S06-advanced/wrap.t @@ -1262,7 +1370,10 @@ t/spec/S06-currying/slurpy.t t/spec/S06-macros/errors.t t/spec/S06-macros/opaque-ast.t +t/spec/S06-macros/postfix.t t/spec/S06-macros/quasi-blocks.t +t/spec/S06-macros/returning-closure.t +t/spec/S06-macros/returning-string.t t/spec/S06-macros/unquoting.t t/spec/S06-multi/by-trait.t t/spec/S06-multi/lexical-multis.t @@ -1274,8 +1385,11 @@ t/spec/S06-multi/type-based.t t/spec/S06-multi/unpackability.t t/spec/S06-multi/value-based.t +t/spec/S06-operator-overloading/circumfix.t t/spec/S06-operator-overloading/imported-subs.t +t/spec/S06-operator-overloading/infix.t t/spec/S06-operator-overloading/methods.t +t/spec/S06-operator-overloading/prefix.t t/spec/S06-operator-overloading/semicolon.t t/spec/S06-operator-overloading/sub.t t/spec/S06-operator-overloading/term.t @@ -1283,6 +1397,7 @@ t/spec/S06-other/anon-hashes-vs-blocks.t t/spec/S06-other/introspection.t t/spec/S06-other/main-eval.t +t/spec/S06-other/main-refactored.t t/spec/S06-other/main-semicolon.t t/spec/S06-other/main.t t/spec/S06-other/main-usage.t @@ -1294,7 +1409,6 @@ t/spec/S06-routine-modifiers/proxy.t t/spec/S06-routine-modifiers/scoped-named-subs.t t/spec/S06-signature/arity.t -t/spec/S06-signature/caller-param.t t/spec/S06-signature/closure-over-parameters.t t/spec/S06-signature/closure-parameters.t t/spec/S06-signature/code.t @@ -1305,6 +1419,7 @@ t/spec/S06-signature/mixed-placeholders.t t/spec/S06-signature/multidimensional.t t/spec/S06-signature/multi-invocant.t +t/spec/S06-signature/multiple-signatures.t t/spec/S06-signature/named-parameters.t t/spec/S06-signature/named-placeholders.t t/spec/S06-signature/named-renaming.t @@ -1318,6 +1433,7 @@ t/spec/S06-signature/shape.t t/spec/S06-signature/sigilless.t t/spec/S06-signature/slurpy-and-interpolation.t +t/spec/S06-signature/slurpy-blocks.t t/spec/S06-signature/slurpy-params.t t/spec/S06-signature/slurpy-placeholders.t t/spec/S06-signature/sub-ref.t @@ -1337,8 +1453,10 @@ t/spec/S06-traits/native-is-rw.t t/spec/S06-traits/precedence.t t/spec/S06-traits/slurpy-is-rw.t -t/spec/S07-hyperrace/hyper.t -t/spec/S07-hyperrace/race.t +t/spec/S07-hyperrace/basics.t +t/spec/S07-hyperrace/for.t +t/spec/S07-hyperrace/stress.t +t/spec/S07-iterators/range-iterator.t t/spec/S07-slip/slip.t t/spec/S09-autovivification/autoincrement.t t/spec/S09-autovivification/autovivification.t @@ -1357,27 +1475,48 @@ t/spec/S09-typed-arrays/native-decl.t t/spec/S09-typed-arrays/native-int.t t/spec/S09-typed-arrays/native-num.t +t/spec/S09-typed-arrays/native-str.t t/spec/S09-typed-arrays/native.t t/spec/S10-packages/basic.t +t/spec/S10-packages/export.t t/spec/S10-packages/joined-namespaces.t +t/spec/S10-packages/nested-use.t t/spec/S10-packages/precompilation.t t/spec/S10-packages/README +t/spec/S10-packages/require-and-use--dead-file.t +t/spec/S10-packages/require-and-use.t +t/spec/S10-packages/scope.t t/spec/S10-packages/use-with-class.t t/spec/S11-compunit/compunit-dependencyspecification.t t/spec/S11-compunit/compunit-repository.t t/spec/S11-compunit/rt126904.t t/spec/S11-modules/export.t +t/spec/S11-modules/GlobalInner.pm6 +t/spec/S11-modules/GlobalOuter.pm6 t/spec/S11-modules/importing.t t/spec/S11-modules/import-multi.t t/spec/S11-modules/import.t t/spec/S11-modules/import-tag.t -t/spec/S11-modules/InnerModule.pm +t/spec/S11-modules/InnerModule.pm6 t/spec/S11-modules/lexical.t +t/spec/S11-modules/lib/Cool/Beans.pm6 +t/spec/S11-modules/lib/Cool/Cat/Goes/Splat.pm6 +t/spec/S11-modules/lib/Cool/Cat.pm6 +t/spec/S11-modules/lib/Cool/Utils.pm6 +t/spec/S11-modules/module-file.t +t/spec/S11-modules/module.t t/spec/S11-modules/need.t t/spec/S11-modules/nested.t -t/spec/S11-modules/OuterModule.pm +t/spec/S11-modules/NoModule.pm6 +t/spec/S11-modules/OuterModule.pm6 +t/spec/S11-modules/perl6lib.t +t/spec/S11-modules/re-export.t t/spec/S11-modules/require.t +t/spec/S11-modules/runtime.t +t/spec/S11-modules/SetConst.pm6 +t/spec/S11-modules/use-perl-6.t t/spec/S11-repository/curli-install.t +t/spec/S12-attributes/augment-and-initialization.t t/spec/S12-attributes/class.t t/spec/S12-attributes/clone.t t/spec/S12-attributes/defaults.t @@ -1388,6 +1527,7 @@ t/spec/S12-attributes/native.t t/spec/S12-attributes/recursive.t t/spec/S12-attributes/smiley.t +t/spec/S12-attributes/trusts.t t/spec/S12-attributes/undeclared.t t/spec/S12-class/anonymous.t t/spec/S12-class/attributes-required.t @@ -1405,6 +1545,7 @@ t/spec/S12-class/magical-vars.t t/spec/S12-class/mro.t t/spec/S12-class/namespaced.t +t/spec/S12-class/open_closed.t t/spec/S12-class/open.t t/spec/S12-class/parent_attributes.t t/spec/S12-class/rw.t @@ -1415,8 +1556,10 @@ t/spec/S12-construction/autopairs.t t/spec/S12-construction/BUILD.t t/spec/S12-construction/construction.t +t/spec/S12-construction/destruction.t t/spec/S12-construction/named-params-in-BUILD.t t/spec/S12-construction/new.t +t/spec/S12-construction/TWEAK.t t/spec/S12-enums/anonymous.t t/spec/S12-enums/as-role.t t/spec/S12-enums/basic.t @@ -1433,15 +1576,18 @@ t/spec/S12-introspection/roles.t t/spec/S12-introspection/walk.t t/spec/S12-introspection/WHAT.t -t/spec/S12-meta/DeclareBad.pm -t/spec/S12-meta/Declare.pm +t/spec/S12-meta/classhow.t +t/spec/S12-meta/DeclareBad.pm6 +t/spec/S12-meta/Declare.pm6 t/spec/S12-meta/exporthow.t t/spec/S12-meta/grammarhow.t -t/spec/S12-meta/InvalidDirective.pm +t/spec/S12-meta/InvalidDirective.pm6 +t/spec/S12-meta/MultiDeclare.pm6 t/spec/S12-meta/primitives.t -t/spec/S12-meta/Supersede1.pm -t/spec/S12-meta/Supersede2.pm -t/spec/S12-meta/SupersedeBad.pm +t/spec/S12-meta/Supersede1.pm6 +t/spec/S12-meta/Supersede2.pm6 +t/spec/S12-meta/SupersedeBad.pm6 +t/spec/S12-meta/TestHOW.pm6 t/spec/S12-methods/accessors.t t/spec/S12-methods/attribute-params.t t/spec/S12-methods/calling_sets.t @@ -1471,9 +1617,14 @@ t/spec/S12-methods/what.t t/spec/S12-subset/multi-dispatch.t t/spec/S12-subset/subtypes.t +t/spec/S12-traits/basic.t +t/spec/S12-traits/parameterized.t +t/spec/S13-overloading/fallbacks-deep.t t/spec/S13-overloading/metaoperators.t +t/spec/S13-overloading/multiple-signatures.t t/spec/S13-overloading/operators.t t/spec/S13-overloading/typecasting-long.t +t/spec/S13-syntax/aliasing.t t/spec/S13-type-casting/methods.t t/spec/S14-roles/anonymous.t t/spec/S14-roles/attributes.t @@ -1493,28 +1644,33 @@ t/spec/S14-roles/stubs.t t/spec/S14-roles/submethods.t t/spec/S14-traits/attributes.t +t/spec/S14-traits/package.t t/spec/S14-traits/routines.t +t/spec/S14-traits/variables.t t/spec/S15-literals/identifiers.t t/spec/S15-literals/numbers.t t/spec/S15-nfg/case-change.t t/spec/S15-nfg/cgj.t t/spec/S15-nfg/concatenation.t +t/spec/S15-nfg/concat-stable.t t/spec/S15-nfg/crlf-encoding.t +t/spec/S15-nfg/emoji-test-gen.p6 +t/spec/S15-nfg/emoji-test.t t/spec/S15-nfg/from-buf.t t/spec/S15-nfg/from-file.t t/spec/S15-nfg/grapheme-break.t -t/spec/S15-nfg/grapheme-break-test-gen.p6 +t/spec/S15-nfg/GraphemeBreakTest.t t/spec/S15-nfg/long-uni.t t/spec/S15-nfg/many-combiners.t t/spec/S15-nfg/many-threads.t -t/spec/S15-nfg/mass-chars.t +t/spec/S15-nfg/mass-equality-gen.p6 t/spec/S15-nfg/mass-equality.t t/spec/S15-nfg/mass-roundtrip-nfc.t t/spec/S15-nfg/mass-roundtrip-nfd.t t/spec/S15-nfg/mass-roundtrip-nfkc.t t/spec/S15-nfg/mass-roundtrip-nfkd.t +t/spec/S15-nfg/mass-roundtrip-test-gen.p6 t/spec/S15-nfg/regex.t -t/spec/S15-nfg/test-gen.p6 t/spec/S15-normalization/nfc-0.t t/spec/S15-normalization/nfc-1.t t/spec/S15-normalization/nfc-2.t @@ -1525,6 +1681,7 @@ t/spec/S15-normalization/nfc-7.t t/spec/S15-normalization/nfc-8.t t/spec/S15-normalization/nfc-9.t +t/spec/S15-normalization/nfc-concat.t t/spec/S15-normalization/nfc-sanity.t t/spec/S15-normalization/nfd-0.t t/spec/S15-normalization/nfd-1.t @@ -1560,6 +1717,8 @@ t/spec/S15-normalization/nfkd-9.t t/spec/S15-normalization/nfkd-sanity.t t/spec/S15-normalization/test-gen.p6 +t/spec/S15-string-types/NFK-types.t +t/spec/S15-string-types/NF-types.t t/spec/S15-string-types/Str.t t/spec/S15-string-types/Uni.t t/spec/S15-unicode-information/unimatch-general.t @@ -1568,12 +1727,15 @@ t/spec/S15-unicode-information/unival.t t/spec/S16-filehandles/argfiles.t t/spec/S16-filehandles/chmod.t +t/spec/S16-filehandles/dir.t t/spec/S16-filehandles/filestat.t t/spec/S16-filehandles/filetest.t t/spec/S16-filehandles/io_in_for_loops.t t/spec/S16-filehandles/io_in_while_loops.t t/spec/S16-filehandles/io.t +t/spec/S16-filehandles/misc.t t/spec/S16-filehandles/mkdir_rmdir.t +t/spec/S16-filehandles/mode.t t/spec/S16-filehandles/open.t t/spec/S16-filehandles/unlink.t t/spec/S16-io/bare-say.t @@ -1581,11 +1743,17 @@ t/spec/S16-io/bom.t t/spec/S16-io/comb.t t/spec/S16-io/cwd.t +t/spec/S16-io/eof.t t/spec/S16-io/getc.t +t/spec/S16-io/handles-between-threads.t +t/spec/S16-io/home.t t/spec/S16-io/lines.t t/spec/S16-io/newline.t t/spec/S16-io/note.t t/spec/S16-io/print.t +t/spec/S16-io/prompt.t +t/spec/S16-io/put.t +t/spec/S16-io/readchars.t t/spec/S16-io/say-and-ref.t t/spec/S16-io/say.t t/spec/S16-io/split.t @@ -1593,21 +1761,38 @@ t/spec/S16-io/test-data t/spec/S16-io/tmpdir.t t/spec/S16-io/words.t +t/spec/S16-unfiled/getpeername.t t/spec/S16-unfiled/rebindstdhandles.t t/spec/S17-channel/basic.t +t/spec/S17-channel/stress.t +t/spec/S17-lowlevel/atomic-ops.t +t/spec/S17-lowlevel/atomic.t +t/spec/S17-lowlevel/cas-int.t +t/spec/S17-lowlevel/cas-loop-int.t +t/spec/S17-lowlevel/cas-loop.t +t/spec/S17-lowlevel/cas.t t/spec/S17-lowlevel/lock.t +t/spec/S17-lowlevel/semaphore.t t/spec/S17-lowlevel/thread-start-join-stress.t t/spec/S17-lowlevel/thread.t t/spec/S17-procasync/basic.t +t/spec/S17-procasync/bind-handles.t +t/spec/S17-procasync/encoding.t t/spec/S17-procasync/kill.t t/spec/S17-procasync/many-processes-no-close-stdin.t +t/spec/S17-procasync/nonexistent.t t/spec/S17-procasync/no-runaway-file-limit.t t/spec/S17-procasync/print.t +t/spec/S17-procasync/stress.t t/spec/S17-promise/allof.t t/spec/S17-promise/anyof.t t/spec/S17-promise/at.t t/spec/S17-promise/basic.t t/spec/S17-promise/in.t +t/spec/S17-promise/lock-async-stress2.t +t/spec/S17-promise/lock-async-stress.t +t/spec/S17-promise/lock-async.t +t/spec/S17-promise/nonblocking-await.t t/spec/S17-promise/start.t t/spec/S17-promise/stress.t t/spec/S17-promise/then.t @@ -1643,13 +1828,18 @@ t/spec/S17-supply/produce.t t/spec/S17-supply/Promise.t t/spec/S17-supply/reduce.t +t/spec/S17-supply/return-in-tap.t t/spec/S17-supply/reverse.t t/spec/S17-supply/rotor.t t/spec/S17-supply/schedule-on.t +t/spec/S17-supply/Seq.t +t/spec/S17-supply/skip.t t/spec/S17-supply/sort.t t/spec/S17-supply/squish.t t/spec/S17-supply/stable.t t/spec/S17-supply/start.t +t/spec/S17-supply/supplier-preserving.t +t/spec/S17-supply/syntax-nonblocking-await.t t/spec/S17-supply/syntax.t t/spec/S17-supply/tail.t t/spec/S17-supply/throttle.t @@ -1662,12 +1852,28 @@ t/spec/S19-command-line/arguments.t t/spec/S19-command-line/dash-e.t t/spec/S19-command-line/help.t +t/spec/S19-command-line-options/01-dash-uppercase-i.t t/spec/S19-command-line-options/02-dash-n.t t/spec/S19-command-line-options/03-dash-p.t +t/spec/S19-command-line-options/04-negation.t +t/spec/S19-command-line-options/05-delimited-options.t t/spec/S19-command-line/repl.t t/spec/S22-package-format/local.t t/spec/S24-testing/0-compile.t +t/spec/S24-testing/10-is-approx.t +t/spec/S24-testing/11-plan-skip-all-subtests.t +t/spec/S24-testing/11-plan-skip-all.t +t/spec/S24-testing/12-subtest-todo.t +t/spec/S24-testing/13-cmp-ok.t +t/spec/S24-testing/14-like-unlike.t +t/spec/S24-testing/1-basic.t +t/spec/S24-testing/2-force_todo.t t/spec/S24-testing/3-output.t +t/spec/S24-testing/6-done_testing.t +t/spec/S24-testing/7-bail_out.t +t/spec/S24-testing/8-die_on_fail.t +t/spec/S24-testing/9-is_deeply.t +t/spec/S24-testing/fails-like.t t/spec/S24-testing/line-numbers.t t/spec/S24-testing/test-data/line-number-cmp-ok.txt t/spec/S24-testing/test-data/line-number-dies-ok.txt @@ -1684,17 +1890,26 @@ t/spec/S24-testing/test-data/line-number-throws-like.txt t/spec/S24-testing/test-data/README t/spec/S24-testing/test-data/todo-passed.txt -t/spec/S24-testing/use_ok_test.pm +t/spec/S24-testing/use_ok_test.pm6 t/spec/S26-documentation/01-delimited.t t/spec/S26-documentation/02-paragraph.t t/spec/S26-documentation/03-abbreviated.t +t/spec/S26-documentation/04a-input-output.t t/spec/S26-documentation/04-code.t t/spec/S26-documentation/05-comment.t t/spec/S26-documentation/06-lists.t +t/spec/S26-documentation/07a-tables.t +t/spec/S26-documentation/07b-tables.t +t/spec/S26-documentation/07c-tables.t t/spec/S26-documentation/07-tables.t t/spec/S26-documentation/08-formattingcodes.t t/spec/S26-documentation/09-configuration.t t/spec/S26-documentation/10-doc-cli.t +t/spec/S26-documentation/11-non-breaking-space.t +t/spec/S26-documentation/12-non-breaking-space.t +t/spec/S26-documentation/13-space-chars.t +t/spec/S26-documentation/14-defn.t +t/spec/S26-documentation/15-numbered-alias.t t/spec/S26-documentation/block-leading.t t/spec/S26-documentation/block-trailing.t t/spec/S26-documentation/module-comment.t @@ -1705,9 +1920,12 @@ t/spec/S26-documentation/why-leading.t t/spec/S26-documentation/why-trailing.t t/spec/S28-named-variables/cwd.t +t/spec/S28-named-variables/init-instant.t t/spec/S28-named-variables/slangs.t t/spec/S29-any/cmp.t +t/spec/S29-any/deg-trans.t t/spec/S29-any/isa.t +t/spec/S29-any/minpairs-maxpairs.t t/spec/S29-context/die.t t/spec/S29-context/evalfile.t t/spec/S29-context/eval.t @@ -1736,14 +1954,20 @@ t/spec/S32-array/shift.t t/spec/S32-array/splice.t t/spec/S32-array/unshift.t +t/spec/S32-basics/pairup.t t/spec/S32-basics/warn.t t/spec/S32-basics/xxKEY.t t/spec/S32-basics/xxPOS-native.t t/spec/S32-basics/xxPOS.t +t/spec/S32-container/buf.t t/spec/S32-container/cat.t t/spec/S32-container/roundrobin.t t/spec/S32-container/stringify.t t/spec/S32-container/zip.t +t/spec/S32-encoding/decoder.t +t/spec/S32-encoding/encoder.t +t/spec/S32-encoding/registry.t +t/spec/S32-exceptions/misc2.t t/spec/S32-exceptions/misc.t t/spec/S32-hash/adverbs.t t/spec/S32-hash/antipairs.t @@ -1752,62 +1976,96 @@ t/spec/S32-hash/exists-adverb.t t/spec/S32-hash/exists.t t/spec/S32-hash/invert.t +t/spec/S32-hash/iterator.t t/spec/S32-hash/keys_values.t t/spec/S32-hash/kv.t +t/spec/S32-hash/map.t t/spec/S32-hash/pairs.t t/spec/S32-hash/perl.t t/spec/S32-hash/push.t t/spec/S32-hash/slice.t +t/spec/S32-io/chdir-process.t t/spec/S32-io/chdir.t t/spec/S32-io/copy.t t/spec/S32-io/dir.t t/spec/S32-io/empty.txt t/spec/S32-io/file-tests.t +t/spec/S32-io/indir.t +t/spec/S32-io/io-cathandle.t t/spec/S32-io/io-handle.t t/spec/S32-io/io-path-cygwin.t +t/spec/S32-io/io-path-extension.t +t/spec/S32-io/io-path-subclasses.t +t/spec/S32-io/io-path-symlink.t t/spec/S32-io/io-path.t t/spec/S32-io/io-path-unix.t t/spec/S32-io/io-path-win.t t/spec/S32-io/IO-Socket-Async.t t/spec/S32-io/IO-Socket-Async-UDP.t -t/spec/S32-io/IO-Socket-INET.bat -t/spec/S32-io/IO-Socket-INET.pl -t/spec/S32-io/IO-Socket-INET.sh t/spec/S32-io/IO-Socket-INET.t t/spec/S32-io/io-spec-cygwin.t +t/spec/S32-io/io-special.t +t/spec/S32-io/io-spec-qnx.t t/spec/S32-io/io-spec-unix.t t/spec/S32-io/io-spec-win.t +t/spec/S32-io/lock.t +t/spec/S32-io/mkdir_rmdir.t t/spec/S32-io/move.t t/spec/S32-io/native-descriptor.t t/spec/S32-io/note.t +t/spec/S32-io/null-char.t t/spec/S32-io/open.t +t/spec/S32-io/other-stress.t t/spec/S32-io/other.t +t/spec/S32-io/out-buffering.t t/spec/S32-io/pipe.t t/spec/S32-io/pi.txt t/spec/S32-io/rename.t +t/spec/S32-io/seek.t t/spec/S32-io/slurp.t +t/spec/S32-io/socket-accept-and-working-threads.t +t/spec/S32-io/socket-fail-invalid-values.t +t/spec/S32-io/socket-host-port-split.t t/spec/S32-io/socket-recv-vs-read.t t/spec/S32-io/socket-test.bin t/spec/S32-io/spurt.t +t/spec/S32-io/tell.t +t/spec/S32-io/utf16.t +t/spec/S32-io/utf16-test/sample-UTF-16BE-bom.txt +t/spec/S32-io/utf16-test/sample-UTF-16BE.txt +t/spec/S32-io/utf16-test/sample-UTF-16LE-bom.txt +t/spec/S32-io/utf16-test/sample-UTF-16LE.txt +t/spec/S32-io/utf16-test/sample-UTF-16.txt +t/spec/S32-io/utf16-test/sample-UTF-8.txt +t/spec/S32-list/batch.t +t/spec/S32-list/categorize-list.t t/spec/S32-list/categorize.t +t/spec/S32-list/classify-list.t t/spec/S32-list/classify.t t/spec/S32-list/combinations.t t/spec/S32-list/create.t +t/spec/S32-list/cross.t +t/spec/S32-list/deepmap.t +t/spec/S32-list/duckmap.t t/spec/S32-list/end.t t/spec/S32-list/first-end-k.t +t/spec/S32-list/first-end-kv.t t/spec/S32-list/first-end-p.t t/spec/S32-list/first-end.t t/spec/S32-list/first-end-v.t t/spec/S32-list/first-k.t +t/spec/S32-list/first-kv.t t/spec/S32-list/first-p.t t/spec/S32-list/first.t t/spec/S32-list/first-v.t +t/spec/S32-list/flat.t t/spec/S32-list/grep-k.t t/spec/S32-list/grep-kv.t t/spec/S32-list/grep-p.t t/spec/S32-list/grep.t t/spec/S32-list/grep-v.t t/spec/S32-list/head.t +t/spec/S32-list/iterator.t t/spec/S32-list/join.t t/spec/S32-list/map_function_return_values.t t/spec/S32-list/map.t @@ -1822,6 +2080,7 @@ t/spec/S32-list/roll.t t/spec/S32-list/rotor.t t/spec/S32-list/seq.t +t/spec/S32-list/skip.t t/spec/S32-list/sort.t t/spec/S32-list/squish.t t/spec/S32-list/tail.t @@ -1837,6 +2096,7 @@ t/spec/S32-num/is-prime.t t/spec/S32-num/log.t t/spec/S32-num/narrow.t +t/spec/S32-num/negative-zero.t t/spec/S32-num/pi.t t/spec/S32-num/polar.t t/spec/S32-num/polymod.t @@ -1849,6 +2109,7 @@ t/spec/S32-num/rshift_pos_amount.t t/spec/S32-num/sign.t t/spec/S32-num/sqrt.t +t/spec/S32-num/stress.t t/spec/S32-num/stringify.t t/spec/S32-num/unpolar.t t/spec/S32-scalar/defined.t @@ -1859,6 +2120,12 @@ t/spec/S32-str/capitalize.t t/spec/S32-str/chomp.t t/spec/S32-str/chop.t +t/spec/S32-str/Collation.t +t/spec/S32-str/CollationTestGen.p6 +t/spec/S32-str/CollationTest_NON_IGNORABLE-0.t +t/spec/S32-str/CollationTest_NON_IGNORABLE-1.t +t/spec/S32-str/CollationTest_NON_IGNORABLE-2.t +t/spec/S32-str/CollationTest_NON_IGNORABLE-3.t t/spec/S32-str/comb.t t/spec/S32-str/contains.t t/spec/S32-str/encode.t @@ -1874,10 +2141,12 @@ t/spec/S32-str/numeric.t t/spec/S32-str/ords.t t/spec/S32-str/pack.t +t/spec/S32-str/parse-base.t t/spec/S32-str/pos.t t/spec/S32-str/rindex.t t/spec/S32-str/samecase.t t/spec/S32-str/samemark.t +t/spec/S32-str/shiftjis-encode-decode.t t/spec/S32-str/split-simple.t t/spec/S32-str/split.t t/spec/S32-str/sprintf-b.t @@ -1888,16 +2157,21 @@ t/spec/S32-str/substr.t t/spec/S32-str/tclc.t t/spec/S32-str/tc.t +t/spec/S32-str/text-samples/shiftjis_sample_in_utf8.txt +t/spec/S32-str/text-samples/shiftjis_sample.txt t/spec/S32-str/trim.t t/spec/S32-str/uc.t +t/spec/S32-str/uniparse.t t/spec/S32-str/unpack.t t/spec/S32-str/utf8-c8.t +t/spec/S32-str/windows-1251-windows-1252-encode-decode.t t/spec/S32-str/words.t t/spec/S32-temporal/calendar.t t/spec/S32-temporal/Date.t t/spec/S32-temporal/DateTime-Instant-Duration.t t/spec/S32-temporal/DateTime.t t/spec/S32-temporal/local.t +t/spec/S32-temporal/time.t t/spec/S32-trig/atan2.t t/spec/S32-trig/cosech.t t/spec/S32-trig/cosec.t @@ -1917,8 +2191,10 @@ t/spec/S32-trig/tan.t t/spec/S32-trig/trig_functions t/spec/S32-trig/TrigTestSupport +t/spec/super-fudger.p6 t/spec/t/01-implname.in t/spec/t/01-implname.out_impl-1 +t/spec/t/01-implname.out_impl-1.backend t/spec/t/01-implname.out_impl-2 t/spec/t/02-version.in t/spec/t/02-version.out_v6.0.0 @@ -1939,8 +2215,11 @@ t/spectest.data.6.c t/spectest.js.data t/spec/test_summary +t/spec/t/fudgeandrun.t t/spec/t/fudge.t t/spec/TODO +t/spec/tools/spec-review.p6 t/spec/t/README +t/spec/t/test-util/01-is-eqv.t t/spec/VERSION VERSION diff -Nru rakudo-2018.10/src/core/Any-iterable-methods.pm6 rakudo-2018.12/src/core/Any-iterable-methods.pm6 --- rakudo-2018.10/src/core/Any-iterable-methods.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Any-iterable-methods.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1849,7 +1849,7 @@ } proto method pairup(|) is nodal {*} - multi method pairup(Any:U:) { () } + multi method pairup(Any:U:) { ().Seq } multi method pairup(Any:D:) { my \iter := self.iterator; gather { @@ -1957,68 +1957,79 @@ Seq.new( $iter.skip-at-least($n) ?? $iter !! Rakudo::Iterator.Empty ) } + # Note that the implementation of minpairs/maxpairs only differs in the + # value against which the result of cmp is compared (-1 for minpairs, + # +1 for maxpairs). Abstracting the logic in a helper sub, did not change + # the binary size significantly, but would introduce a runtime penalty. + # Hence the almost identical pieces of code here. proto method minpairs(|) {*} multi method minpairs(Any:D:) { - Seq.new( - nqp::if( - nqp::eqaddr( - (my $pulled := (my $iter := self.pairs.iterator).pull-one), - IterationEnd - ), - Rakudo::Iterator.Empty, - nqp::stmts( - nqp::push((my $result := nqp::create(IterationBuffer)),$pulled), - (my $min := $pulled.value), - nqp::until( - nqp::eqaddr(($pulled := $iter.pull-one),IterationEnd), + my \iter := self.pairs.iterator; + my \result := nqp::create(IterationBuffer); + nqp::until( + nqp::eqaddr((my \pair := iter.pull-one),IterationEnd) + || nqp::isconcrete(my \target := pair.value), + nqp::null + ); + nqp::unless( + nqp::eqaddr(pair,IterationEnd), + nqp::stmts( # found at least one value + nqp::push(result,pair), + nqp::until( + nqp::eqaddr(nqp::bind(pair,iter.pull-one),IterationEnd), + nqp::if( + nqp::isconcrete(my \value := pair.value), nqp::if( - nqp::iseq_i((my $cmp := $pulled.value cmp $min), -1), - nqp::stmts( - nqp::push(nqp::setelems($result,0),$pulled), - ($min := $pulled.value) + nqp::iseq_i((my \cmp-result := value cmp target),-1), + nqp::stmts( # new best + nqp::push(nqp::setelems(result,0),pair), + nqp::bind(target,value) ), - nqp::if( - nqp::iseq_i($cmp,0), - nqp::push($result,$pulled) + nqp::if( # additional best + nqp::iseq_i(cmp-result,0), + nqp::push(result,pair) ) ) - ), - Rakudo::Iterator.ReifiedList($result) + ) ) ) - ) + ); + Seq.new(Rakudo::Iterator.ReifiedList(result)) } proto method maxpairs(|) {*} multi method maxpairs(Any:D:) { - Seq.new( - nqp::if( - nqp::eqaddr( - (my $pulled := (my $iter := self.pairs.iterator).pull-one), - IterationEnd - ), - Rakudo::Iterator.Empty, - nqp::stmts( - nqp::push((my $result := nqp::create(IterationBuffer)),$pulled), - (my $max := $pulled.value), - nqp::until( - nqp::eqaddr(($pulled := $iter.pull-one),IterationEnd), + my \iter := self.pairs.iterator; + my \result := nqp::create(IterationBuffer); + nqp::until( + nqp::eqaddr((my \pair := iter.pull-one),IterationEnd) + || nqp::isconcrete(my \target := pair.value), + nqp::null + ); + nqp::unless( + nqp::eqaddr(pair,IterationEnd), + nqp::stmts( # found at least one value + nqp::push(result,pair), + nqp::until( + nqp::eqaddr(nqp::bind(pair,iter.pull-one),IterationEnd), + nqp::if( + nqp::isconcrete(my \value := pair.value), nqp::if( - nqp::iseq_i((my $cmp := $pulled.value cmp $max), 1), - nqp::stmts( - nqp::push(nqp::setelems($result,0),$pulled), - ($max := $pulled.value) + nqp::iseq_i((my \cmp-result := value cmp target),+1), + nqp::stmts( # new best + nqp::push(nqp::setelems(result,0),pair), + nqp::bind(target,value) ), - nqp::if( - nqp::iseq_i($cmp,0), - nqp::push($result,$pulled) + nqp::if( # additional best + nqp::iseq_i(cmp-result,0), + nqp::push(result,pair) ) ) - ), - Rakudo::Iterator.ReifiedList($result) + ) ) ) - ) + ); + Seq.new(Rakudo::Iterator.ReifiedList(result)) } proto method batch(|) is nodal {*} diff -Nru rakudo-2018.10/src/core/Array.pm6 rakudo-2018.12/src/core/Array.pm6 --- rakudo-2018.10/src/core/Array.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Array.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -237,16 +237,24 @@ nqp::p6bindattrinvres(nqp::create(Array),List,'$!reified',reified) } + # handle non-straightforward shapes + method !difficult-shape(\shape) { + nqp::if( + Metamodel::EnumHOW.ACCEPTS(shape.HOW), + set-shape(self,shape.^elems), + nqp::stmts( + warn("Ignoring [{ shape.^name }] as shape specification, did you mean 'my { shape.^name } @foo' ?"), + nqp::create(self) + ) + ) + } + proto method new(|) {*} multi method new(:$shape!) { nqp::if( - nqp::defined($shape), + nqp::isconcrete($shape), set-shape(self,$shape), - nqp::if( - Metamodel::EnumHOW.ACCEPTS($shape.HOW), - set-shape(self,$shape.^elems), - nqp::create(self) - ) + self!difficult-shape($shape) ) } multi method new() { @@ -254,13 +262,9 @@ } multi method new(\values, :$shape!) { nqp::if( - nqp::defined($shape), + nqp::isconcrete($shape), set-shape(self,$shape), - nqp::if( - Metamodel::EnumHOW.ACCEPTS($shape.HOW), - set-shape(self,$shape.^elems), - nqp::create(self) - ) + self!difficult-shape($shape) ).STORE(values) } multi method new(\values) { @@ -268,13 +272,9 @@ } multi method new(**@values is raw, :$shape!) { nqp::if( - nqp::defined($shape), + nqp::isconcrete($shape), set-shape(self,$shape), - nqp::if( - Metamodel::EnumHOW.ACCEPTS($shape.HOW), - set-shape(self,$shape.^elems), - nqp::create(self) - ) + self!difficult-shape($shape) ).STORE(@values) } multi method new(**@values is raw) { diff -Nru rakudo-2018.10/src/core/Attribute.pm6 rakudo-2018.12/src/core/Attribute.pm6 --- rakudo-2018.10/src/core/Attribute.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Attribute.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -164,46 +164,35 @@ # None by default. } - method get_value(Mu $obj) { + method get_value(Mu $obj) is raw { nqp::if( - nqp::iseq_i((my int $t = nqp::objprimspec($!type)),0), - nqp::getattr(nqp::decont($obj),$!package,$!name), + (my int $t = nqp::objprimspec($!type)), nqp::if( nqp::iseq_i($t,1), - nqp::p6box_i(nqp::getattr_i(nqp::decont($obj),$!package,$!name)), + nqp::getattr_i(nqp::decont($obj),$!package,$!name), nqp::if( nqp::iseq_i($t,2), - nqp::p6box_n(nqp::getattr_n(nqp::decont($obj), - $!package,$!name)), - nqp::if( - nqp::iseq_i($t,3), - nqp::p6box_s(nqp::getattr_s(nqp::decont($obj), - $!package,$!name)) - ) + nqp::getattr_n(nqp::decont($obj),$!package,$!name), + nqp::getattr_s(nqp::decont($obj),$!package,$!name) # assume 3 ) - ) + ), + nqp::getattr(nqp::decont($obj),$!package,$!name) ) } - method set_value(Mu $obj, Mu \value) { + method set_value(Mu $obj, Mu \value) is raw { nqp::if( - nqp::iseq_i((my int $t = nqp::objprimspec($!type)),0), - nqp::bindattr(nqp::decont($obj),$!package,$!name,value), + (my int $t = nqp::objprimspec($!type)), nqp::if( nqp::iseq_i($t,1), - nqp::p6box_i(nqp::bindattr_i(nqp::decont($obj), - $!package,$!name,value)), + nqp::bindattr_i(nqp::decont($obj),$!package,$!name,value), nqp::if( nqp::iseq_i($t,2), - nqp::p6box_n(nqp::bindattr_n(nqp::decont($obj), - $!package,$!name,value)), - nqp::if( - nqp::iseq_i($t,3), - nqp::p6box_s(nqp::bindattr_s(nqp::decont($obj), - $!package,$!name,value)) - ) + nqp::bindattr_n(nqp::decont($obj),$!package,$!name,value), + nqp::bindattr_s(nqp::decont($obj),$!package,$!name,value) ) - ) + ), + nqp::bindattr(nqp::decont($obj),$!package,$!name,value) ) } diff -Nru rakudo-2018.10/src/core/Baggy.pm6 rakudo-2018.12/src/core/Baggy.pm6 --- rakudo-2018.10/src/core/Baggy.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Baggy.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -12,6 +12,8 @@ # Immutables aspects of Bag/Mix, need to live to Bag/Mix respectively. #--- interface methods + method of() { UInt } + multi method ACCEPTS(Baggy:U: \other --> Bool:D) { other.^does(self) } diff -Nru rakudo-2018.10/src/core/BagHash.pm6 rakudo-2018.12/src/core/BagHash.pm6 --- rakudo-2018.10/src/core/BagHash.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/BagHash.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -12,6 +12,15 @@ ) ) } + multi method STORE(BagHash:D: \objects, \values --> BagHash:D) { + self.SET-SELF( + Rakudo::QuantHash.ADD-OBJECTS-VALUES-TO-BAG( + nqp::create(Rakudo::Internals::IterationSet), + objects.iterator, + values.iterator + ) + ) + } multi method AT-KEY(BagHash:D: \k) is raw { Proxy.new( FETCH => { @@ -203,12 +212,10 @@ ) } - # same as Baggy.values method push-all($target --> IterationEnd) { nqp::while( # doesn't sink $!iter, - $target.push(nqp::getattr( - nqp::iterval(nqp::shift($!iter)),Pair,'$!value')) + $target.push(proxy(nqp::shift($!iter),$!hash)) ) } } diff -Nru rakudo-2018.10/src/core/Bag.pm6 rakudo-2018.12/src/core/Bag.pm6 --- rakudo-2018.10/src/core/Bag.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Bag.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -30,6 +30,15 @@ !! self.SET-SELF(Rakudo::QuantHash.ADD-PAIRS-TO-BAG( nqp::create(Rakudo::Internals::IterationSet), $iterator)) } + multi method STORE(Bag:D: \objects, \values, :$INITIALIZE! --> Bag:D) { + self.SET-SELF( + Rakudo::QuantHash.ADD-OBJECTS-VALUES-TO-BAG( + nqp::create(Rakudo::Internals::IterationSet), + objects.iterator, + values.iterator + ) + ) + } multi method DELETE-KEY(Bag:D: \k) { X::Immutable.new(method => 'DELETE-KEY', typename => self.^name).throw; diff -Nru rakudo-2018.10/src/core/Block.pm6 rakudo-2018.12/src/core/Block.pm6 --- rakudo-2018.10/src/core/Block.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Block.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -66,7 +66,7 @@ method WHY() { if nqp::isnull($!why) { - nextsame + nextsame unless $*COMPILING_CORE_SETTING; } else { $!why.set_docee(self); $!why diff -Nru rakudo-2018.10/src/core/Buf.pm6 rakudo-2018.12/src/core/Buf.pm6 --- rakudo-2018.10/src/core/Buf.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Buf.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1,3 +1,5 @@ +my class Kernel { ... } +my class X::Assignment::RO { ... } my class X::Buf::AsStr { ... } my class X::Buf::Pack { ... } my class X::Buf::Pack::NonASCII { ... } @@ -5,6 +7,23 @@ my class X::Cannot::Lazy { ... } my class X::Experimental { ... } +# these constants temporary until they are available as nqp::const::FOO +constant BINARY_ENDIAN_NATIVE = 0; +constant BINARY_ENDIAN_LITTLE = 1; +constant BINARY_ENDIAN_BIG = 2; + +constant BINARY_SIZE_8_BIT = 0; +constant BINARY_SIZE_16_BIT = 4; +constant BINARY_SIZE_32_BIT = 8; +constant BINARY_SIZE_64_BIT = 12; + +# externalize the endian indicators +enum Endian ( + NativeEndian => BINARY_ENDIAN_NATIVE, + LittleEndian => BINARY_ENDIAN_LITTLE, + BigEndian => BINARY_ENDIAN_BIG, +); + my role Blob[::T = uint8] does Positional[T] does Stringy is repr('VMArray') is array_type(T) { X::NYI.new( feature => "{$?CLASS.^name.comb(/^ \w+ /)}s with native {T.^name}" @@ -41,11 +60,20 @@ nqp::splice(nqp::create(self),@values,0,0) } multi method new(Blob: @values) { - @values.is-lazy - ?? Failure.new(X::Cannot::Lazy.new(:action,:what(self.^name))) - !! self!push-list("initializ",nqp::create(self),@values) + nqp::create(self).STORE(@values, :INITIALIZE) + } + multi method new(Blob: *@values) { + nqp::create(self).STORE(@values, :INITIALIZE) + } + + proto method STORE(Blob:D: |) {*} + multi method STORE(Blob:D: Iterable:D \iterable, :$INITIALIZE) { + $INITIALIZE + ?? iterable.is-lazy + ?? X::Cannot::Lazy.new(:action,:what(self.^name)).throw + !! self!push-list("initializ",self,iterable) + !! X::Assignment::RO.new(:value(self)).throw } - multi method new(Blob: *@values) { self.new(@values) } proto method allocate(|) {*} multi method allocate(Blob:U: Int:D $elements) { @@ -101,6 +129,86 @@ ) } +#?if moar + # for simplicity's sake, these are not multis + method read-int8(::?ROLE:D: int $offset, Endian $? --> int) is raw { + nqp::readint(self,$offset, + nqp::bitor_i(BINARY_SIZE_8_BIT,BINARY_ENDIAN_NATIVE)); + } + method read-int16(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> int + ) is raw { + nqp::readint(self,$offset, + nqp::bitor_i(BINARY_SIZE_16_BIT,$endian)) + } + method read-int32(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> int + ) is raw { + nqp::readint(self,$offset, + nqp::bitor_i(BINARY_SIZE_32_BIT,$endian)) + } + method read-int64(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> int + ) is raw { + nqp::readint(self,$offset, + nqp::bitor_i(BINARY_SIZE_64_BIT,$endian)) + } + method read-int128(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> Int + ) is raw { + my \unsigned := self.read-uint128($offset,$endian); + unsigned >= 1 +< 127 ?? unsigned - 1 +< 128 !! unsigned + } + + method read-uint8(::?ROLE:D: int $offset, Endian $? --> uint) is raw { + nqp::readuint(self,$offset, + nqp::bitor_i(BINARY_SIZE_8_BIT,BINARY_ENDIAN_NATIVE)) + } + method read-uint16(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> uint + ) is raw { + nqp::readuint(self,$offset, + nqp::bitor_i(BINARY_SIZE_16_BIT,$endian)) + } + method read-uint32(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> uint + ) is raw { + nqp::readuint(self,$offset, + nqp::bitor_i(BINARY_SIZE_32_BIT,$endian)) + } + method read-uint64(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> uint + ) is raw { + my \signed := nqp::readuint(self,$offset, + nqp::bitor_i(BINARY_SIZE_64_BIT,$endian)); + signed < 0 ?? signed + 1 +< 64 !! signed + + } + method read-uint128(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> uint + ) is raw { + my \first := self.read-uint64($offset, $endian); + my \second := self.read-uint64($offset + 8, $endian); + $endian == BigEndian + || ($endian == NativeEndian && Kernel.endian == BigEndian) + ?? first +< 64 +| second + !! second +< 64 +| first + } + + method read-num32(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> num + ) is raw { + nqp::readnum(self,$offset, + nqp::bitor_i(BINARY_SIZE_32_BIT,$endian)) + } + method read-num64(::?ROLE:D: + int $offset, Endian $endian = NativeEndian --> num + ) is raw { + nqp::readnum(self,$offset, + nqp::bitor_i(BINARY_SIZE_64_BIT,$endian)) + } +#?endif + multi method Bool(Blob:D:) { nqp::hllbool(nqp::elems(self)) } method Capture(Blob:D:) { self.List.Capture } @@ -527,6 +635,106 @@ !! nqp::bindpos_i(self,$pos,assignee) } + multi method STORE(Buf:D: Blob:D $blob) { + nqp::splice(nqp::setelems(self,0),$blob,0,0) + } + # The "is default" is needed to prevent runtime dispatch errors + multi method STORE(Buf:D: int @values) is default { + nqp::splice(nqp::setelems(self,0),@values,0,0) + } + multi method STORE(Buf:D: Iterable:D \iterable) { + iterable.is-lazy + ?? X::Cannot::Lazy.new(:action,:what(self.^name)).throw + !! self!push-list("initializ",nqp::setelems(self,0),iterable); + } + +#?if moar + # for simplicity's sake, these are not multis + method write-int8(::?ROLE:D: + int $offset, int8 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_8_BIT,$endian)) + } + method write-int16(::?ROLE:D: + int $offset, int16 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_16_BIT,$endian)) + } + method write-int32(::?ROLE:D: + int $offset, int32 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_32_BIT,$endian)) + } + method write-int64(::?ROLE:D: + int $offset, Int:D $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_64_BIT,$endian)) + } + method write-int128(::?ROLE:D: + int $offset, Int:D $value, Endian $endian = NativeEndian --> Nil + ) is raw { + # These uints are intentional to keep the value within 64 bits + my uint $first = ($value +> 64) +& (1 +< 64 - 1); + my uint $second = $value +& (1 +< 64 - 1); + my $be = $endian == BigEndian + || ($endian == NativeEndian && Kernel.endian == BigEndian); + + self.write-int64($offset, $be ?? $first !! $second, $endian); + self.write-int64($offset + 8, $be ?? $second !! $first, $endian); + } + method write-uint8(::?ROLE:D: + int $offset, uint8 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeuint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_8_BIT,$endian)) + } + method write-uint16(::?ROLE:D: + int $offset, uint16 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeuint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_16_BIT,$endian)) + } + method write-uint32(::?ROLE:D: + int $offset, uint32 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeuint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_32_BIT,$endian)) + } + method write-uint64(::?ROLE:D: + int $offset, UInt:D $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writeuint(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_64_BIT,$endian)) + } + method write-uint128(::?ROLE:D: + int $offset, UInt:D $value, Endian $endian = NativeEndian --> Nil + ) is raw { + my \first := $value +> 64; + my \second := $value +& ( 1 +< 64 - 1 ); + my $be = $endian == BigEndian + || ($endian == NativeEndian && Kernel.endian == BigEndian); + + self.write-uint64($offset, $be ?? first !! second, $endian); + self.write-uint64($offset + 8, $be ?? second !! first, $endian); + } + method write-num32(::?ROLE:D: + int $offset, num32 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writenum(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_32_BIT,$endian)) + } + method write-num64(::?ROLE:D: + int $offset, num64 $value, Endian $endian = NativeEndian --> Nil + ) is raw { + nqp::writenum(self,$offset,$value, + nqp::bitor_i(BINARY_SIZE_64_BIT,$endian)) + } +#?endif + multi method list(Buf:D:) { Seq.new(class :: does Rakudo::Iterator::Blobby { method pull-one() is raw { diff -Nru rakudo-2018.10/src/core/Collation.pm6 rakudo-2018.12/src/core/Collation.pm6 --- rakudo-2018.10/src/core/Collation.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Collation.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -12,10 +12,6 @@ Int :$tertiary = 1, Int :$quaternary = 1) { - nqp::isnull(nqp::getlexcaller('EXPERIMENTAL-COLLATION')) and X::Experimental.new( - feature => 'the $*COLLATION dynamic variable', - use => 'collation' - ).throw; my int $i = 0; $i += 1 if $primary.sign == 1; $i += 2 if $primary.sign == -1; diff -Nru rakudo-2018.10/src/core/CompUnit/PrecompilationRepository.pm6 rakudo-2018.12/src/core/CompUnit/PrecompilationRepository.pm6 --- rakudo-2018.10/src/core/CompUnit/PrecompilationRepository.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/CompUnit/PrecompilationRepository.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -249,7 +249,7 @@ %env = $*RESOURCES ?? $*RESOURCES.Str !! '{}'; $RMD("Precompiling $path into $bc ($lle $profile $optimize)") if $RMD; - my $perl6 = $*EXECUTABLE + my $perl6 = $*EXECUTABLE.absolute .subst('perl6-debug', 'perl6') # debugger would try to precompile it's UI .subst('perl6-gdb', 'perl6') .subst('perl6-jdb-server', 'perl6-j') ; @@ -285,7 +285,7 @@ } } - my @result = $out.lines.unique; + my @result is List = $out.lines.unique; if $status { # something wrong self.store.unlock; $RMD("Precompiling $path failed: $status") if $RMD; diff -Nru rakudo-2018.10/src/core/CompUnit/Repository/FileSystem.pm6 rakudo-2018.12/src/core/CompUnit/Repository/FileSystem.pm6 --- rakudo-2018.10/src/core/CompUnit/Repository/FileSystem.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/CompUnit/Repository/FileSystem.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -6,7 +6,7 @@ has $!precomp-stores; has $!precomp-store; - my @extensions = ; + my @extensions := ; my $extensions := nqp::hash('pm6',1,'pm',1); # global cache of files seen diff -Nru rakudo-2018.10/src/core/CompUnit/Repository/Installation.pm6 rakudo-2018.12/src/core/CompUnit/Repository/Installation.pm6 --- rakudo-2018.10/src/core/CompUnit/Repository/Installation.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/CompUnit/Repository/Installation.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -145,7 +145,7 @@ self!bin-dir; if ($version < 1) { for $short-dir.dir -> $file { - my @ids = $file.lines.unique; + my @ids is List = $file.lines.unique; $file.unlink; $file.mkdir; for @ids -> $id { @@ -379,7 +379,7 @@ # Scripts using this interface could only have been installed long after the introduction of # repo version 1, so we don't have to care about very old repos in this method. - my @dists = $lookup.dir.map({ + my @dists is List = $lookup.dir.map({ my ($ver, $auth, $api, $resource-id) = $_.slurp.split("\n"); $resource-id ||= self!read-dist($_.basename){$file}; (id => $_.basename, ver => Version.new( $ver || 0 ), :$auth, :$api, :$resource-id).hash @@ -398,7 +398,7 @@ my $lookup = $prefix.add('short').add(nqp::sha1($name)); if $lookup.e { my $repo-version = self!repository-version; - my @dists = $repo-version < 1 + my @dists is List = $repo-version < 1 ?? $lookup.lines.unique.map({ self!read-dist($_) }) @@ -423,7 +423,7 @@ my $repo-version = self!repository-version; my $lookup = $.prefix.add('short').add(nqp::sha1($spec.short-name)); if $lookup.e { - my @dists = ( + my @dists is List = ( $repo-version < 1 ?? $lookup.lines.unique.map({ $_ => self!read-dist($_) diff -Nru rakudo-2018.10/src/core/CompUnit/RepositoryRegistry.pm6 rakudo-2018.12/src/core/CompUnit/RepositoryRegistry.pm6 --- rakudo-2018.10/src/core/CompUnit/RepositoryRegistry.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/CompUnit/RepositoryRegistry.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -10,6 +10,10 @@ class CompUnit::Repository::Java { ... } #?endif +#?if js +class CompUnit::Repository::FileSystemWithRecording { ... } +#?endif + class CompUnit::RepositoryRegistry { my $lock = Lock.new; my %include-spec2cur; @@ -247,7 +251,7 @@ } method file-for-spec(Str $spec) { - my @parts = $spec.split('#', 2); + my @parts is List = $spec.split('#', 2); if @parts.elems == 2 { my $repo = self.repository-for-name(@parts[0]); return $repo.source-file(@parts[1]) if $repo.can('source-file'); @@ -260,7 +264,8 @@ shift @*ARGS if $auth; shift @*ARGS if $ver; $name //= $dist-name; - my @installations = $*REPO.repo-chain.grep(CompUnit::Repository::Installation); + my @installations is List = + $*REPO.repo-chain.grep(CompUnit::Repository::Installation); my @binaries = @installations.map({ .script("bin/$script", :$name, :$auth, :$ver) }).grep(*.defined); unless +@binaries { @binaries = flat @installations.map: { .script("bin/$script", :$name) }; @@ -336,8 +341,6 @@ } } - # No need to do difficult things at startup when we can precompile this - # into the setting. my %short-id2class = ( 'file', CompUnit::Repository::FileSystem, 'inst', CompUnit::Repository::Installation, @@ -348,6 +351,9 @@ 'javart', CompUnit::Repository::JavaRuntime, 'java', CompUnit::Repository::Java, #?endif +#?if js + 'filerecording', CompUnit::Repository::FileSystemWithRecording, +#?endif ); my $sid-lock := Lock.new; diff -Nru rakudo-2018.10/src/core/Cool.pm6 rakudo-2018.12/src/core/Cool.pm6 --- rakudo-2018.10/src/core/Cool.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Cool.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -337,7 +337,7 @@ proto sub comb($, $, $?, *%) {*} multi sub comb(Regex $matcher, Cool $input, $limit = *) { $input.comb($matcher, $limit) } multi sub comb(Str $matcher, Cool $input, $limit = *) { $input.comb($matcher, $limit) } -multi sub comb(Int:D $matcher, Cool $input, $limit = *) { $input.comb($matcher, $limit) } +multi sub comb(Int:D $size, Cool $input, $limit = *) { $input.comb($size, $limit) } proto sub wordcase($, *%) is pure {*} multi sub wordcase(Str:D $x) {$x.wordcase } diff -Nru rakudo-2018.10/src/core/core_epilogue.pm6 rakudo-2018.12/src/core/core_epilogue.pm6 --- rakudo-2018.10/src/core/core_epilogue.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/core_epilogue.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -24,9 +24,10 @@ } { - my $perl := BEGIN Perl.new; + # XXX TODO: https://github.com/rakudo/rakudo/issues/2433 + # my $perl := BEGIN Perl.new; Rakudo::Internals.REGISTER-DYNAMIC: '$*PERL', { - PROCESS::<$PERL> := $perl; + PROCESS::<$PERL> := Perl.new; } } diff -Nru rakudo-2018.10/src/core/Date.pm6 rakudo-2018.12/src/core/Date.pm6 --- rakudo-2018.10/src/core/Date.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Date.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -30,7 +30,7 @@ :got($day), :range("1..{self!DAYS-IN-MONTH($year,$month)}") ).throw; - self === Date + nqp::eqaddr(self.WHAT,Date) ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter) !! self.bless(:$year,:$month,:$day,:&formatter,|%_) } @@ -43,7 +43,7 @@ :got($day), :range("1..{self!DAYS-IN-MONTH($year,$month)}") ).throw; - self === Date + nqp::eqaddr(self.WHAT,Date) ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter) !! self.bless(:$year,:$month,:$day,:&formatter,|%_) } @@ -62,7 +62,7 @@ self.new($0,$1,$2,:&formatter,|%_) } multi method new(Date: Dateish $d, :&formatter, *%_) { - self === Date + nqp::eqaddr(self.WHAT,Date) ?? nqp::create(self)!SET-SELF($d.year,$d.month,$d.day,&formatter) !! self.bless( :year($d.year), @@ -77,7 +77,7 @@ } method new-from-daycount($daycount,:&formatter) { self!ymd-from-daycount($daycount, my $year, my $month, my $day); - self === Date + nqp::eqaddr(self.WHAT,Date) ?? nqp::create(self)!SET-SELF($year,$month,$day,&formatter,$daycount) !! self.bless(:$year,:$month,:$day,:&formatter,:$daycount) } @@ -104,12 +104,21 @@ } method later(:$earlier, *%unit) { - my @pairs = %unit.pairs; - die "More than one time unit supplied" if @pairs > 1; - die "No time unit supplied" unless @pairs; - my $unit = self!VALID-UNIT(@pairs.AT-POS(0).key); - my $amount = @pairs.AT-POS(0).value.Int; + # basic sanity check + nqp::if( + nqp::eqaddr( + (my \later := (my \iterator := %unit.iterator).pull-one), + IterationEnd + ), + (die "No time unit supplied"), + nqp::unless( + nqp::eqaddr(iterator.pull-one,IterationEnd), + (die "More than one time unit supplied") + ) + ); + my $unit := later.key; + my $amount = later.value; $amount = -$amount if $earlier; if nqp::atkey($valid-units,$unit) -> $multiplier { @@ -138,28 +147,42 @@ method clone(*%_) { my $h := nqp::getattr(%_,Map,'$!storage'); self.new( - nqp::existskey($h,'year') ?? nqp::atkey($h,'year') !! $!year, - nqp::existskey($h,'month') ?? nqp::atkey($h,'month') !! $!month, - nqp::existskey($h,'day') ?? nqp::atkey($h,'day') !! $!day, - formatter => nqp::existskey($h,'formatter') - ?? nqp::atkey($h,'formatter') !! &!formatter, + nqp::ifnull(nqp::atkey($h,'year'), $!year), + nqp::ifnull(nqp::atkey($h,'month'),$!month), + nqp::ifnull(nqp::atkey($h,'day'), $!day), + formatter => nqp::ifnull(nqp::atkey($h,'formatter'),&!formatter), ) } method !clone-without-validating(*%_) { # A premature optimization. my $h := nqp::getattr(%_,Map,'$!storage'); nqp::create(self)!SET-SELF( - nqp::existskey($h,'year') ?? nqp::atkey($h,'year') !! $!year, - nqp::existskey($h,'month') ?? nqp::atkey($h,'month') !! $!month, - nqp::existskey($h,'day') ?? nqp::atkey($h,'day') !! $!day, + nqp::ifnull(nqp::atkey($h,'year'), $!year), + nqp::ifnull(nqp::atkey($h,'month'),$!month), + nqp::ifnull(nqp::atkey($h,'day'), $!day), &!formatter, ) } + method new-from-diff(Date:D: Int:D $diff) { + nqp::isconcrete($!daycount) + ?? nqp::stmts( + (my \new := nqp::clone(self)), + nqp::bindattr(new,Date,'$!day', $!day + $diff), + nqp::bindattr(new,Date,'$!daycount',$!daycount + $diff), + new + ) + !! nqp::p6bindattrinvres(nqp::clone(self),Date,'$!day',$!day + $diff) + } + method succ(Date:D:) { - self.new-from-daycount(self.daycount + 1); + $!day < 28 && nqp::eqaddr(self.WHAT,Date) + ?? self.new-from-diff(1) + !! self.new-from-daycount(self.daycount + 1) } method pred(Date:D:) { - self.new-from-daycount(self.daycount - 1); + $!day > 1 && nqp::eqaddr(self.WHAT,Date) + ?? self.new-from-diff(-1) + !! self.new-from-daycount(self.daycount - 1) } multi method perl(Date:D:) { @@ -176,13 +199,19 @@ } multi sub infix:<+>(Date:D $d, Int:D $x) { - Date.new-from-daycount($d.daycount + $x) + nqp::eqaddr($d.WHAT,Date) && $d.day + $x <= 28 + ?? $d.new-from-diff($x) + !! Date.new-from-daycount($d.daycount + $x) } multi sub infix:<+>(Int:D $x, Date:D $d) { - Date.new-from-daycount($d.daycount + $x) + nqp::eqaddr($d.WHAT,Date) && $d.day + $x <= 28 + ?? $d.new-from-diff($x) + !! Date.new-from-daycount($d.daycount + $x) } multi sub infix:<->(Date:D $d, Int:D $x) { - Date.new-from-daycount($d.daycount - $x) + nqp::eqaddr($d.WHAT,Date) && $d.day - $x > 0 + ?? $d.new-from-diff(-$x) + !! Date.new-from-daycount($d.daycount - $x) } multi sub infix:<->(Date:D $a, Date:D $b) { $a.daycount - $b.daycount; diff -Nru rakudo-2018.10/src/core/DateTime.pm6 rakudo-2018.12/src/core/DateTime.pm6 --- rakudo-2018.10/src/core/DateTime.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/DateTime.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -46,15 +46,16 @@ !! X::DateTime::InvalidDeltaUnit.new(:$unit).throw } - method !SET-SELF(\y,\mo,\d,\h,\mi,\s,\t,\f) { - $!year = y; - $!month = mo; - $!day = d; - $!hour = h; - $!minute = mi; - $!second = s; - $!timezone = t; - &!formatter = f; + method !SET-SELF( + $!year, + $!month, + $!day, + $!hour, + $!minute, + $!second, + $!timezone, + &!formatter, + ) { self } method !new-from-positional(DateTime: @@ -161,7 +162,7 @@ my int $month = $m + 3 - 12 * ($m div 10); my Int $year = $b * 100 + $d - 4800 + $m div 10; - my $dt = self === DateTime + my $dt = nqp::eqaddr(self.WHAT,DateTime) ?? ( %_ ?? die "Unexpected named parameter{"s" if %_ > 1} " ~ %_.keys.map({"`$_`"}).join(", ") ~ " passed. Were you " ~ "trying to use the named parameter form of .new() but " @@ -220,35 +221,36 @@ } method clone(*%_) { - my $h := nqp::getattr(%_,Map,'$!storage'); + my \h := nqp::getattr(%_,Map,'$!storage'); self!new-from-positional( - nqp::existskey($h,'year') ?? nqp::atkey($h,'year') !! $!year, - nqp::existskey($h,'month') ?? nqp::atkey($h,'month') !! $!month, - nqp::existskey($h,'day') ?? nqp::atkey($h,'day') !! $!day, - nqp::existskey($h,'hour') ?? nqp::atkey($h,'hour') !! $!hour, - nqp::existskey($h,'minute') ?? nqp::atkey($h,'minute') !! $!minute, - nqp::existskey($h,'second') ?? nqp::atkey($h,'second') !! $!second, + nqp::ifnull(nqp::atkey(h,'year'), $!year), + nqp::ifnull(nqp::atkey(h,'month'), $!month), + nqp::ifnull(nqp::atkey(h,'day'), $!day), + nqp::ifnull(nqp::atkey(h,'hour'), $!hour), + nqp::ifnull(nqp::atkey(h,'minute'),$!minute), + nqp::ifnull(nqp::atkey(h,'second'),$!second), %_, - timezone => nqp::existskey($h,'timezone') - ?? nqp::atkey($h,'timezone') !! $!timezone, - formatter => nqp::existskey($h,'formatter') - ?? nqp::atkey($h,'formatter') !! &!formatter, + timezone => nqp::ifnull(nqp::atkey(h,'timezone'),$!timezone), + formatter => nqp::ifnull(nqp::atkey(h,'formatter'),&!formatter), ) } method !clone-without-validating(*%_) { # A premature optimization. - return self.clone(|%_) unless self === DateTime; - - my $h := nqp::getattr(%_,Map,'$!storage'); - nqp::create(self)!SET-SELF( - nqp::existskey($h,'year') ?? nqp::atkey($h,'year') !! $!year, - nqp::existskey($h,'month') ?? nqp::atkey($h,'month') !! $!month, - nqp::existskey($h,'day') ?? nqp::atkey($h,'day') !! $!day, - nqp::existskey($h,'hour') ?? nqp::atkey($h,'hour') !! $!hour, - nqp::existskey($h,'minute') ?? nqp::atkey($h,'minute') !! $!minute, - nqp::existskey($h,'second') ?? nqp::atkey($h,'second') !! $!second, - nqp::existskey($h,'timezone') - ?? nqp::atkey($h,'timezone') !! $!timezone, - &!formatter, + nqp::if( + nqp::eqaddr(self.WHAT,DateTime), + nqp::stmts( + (my \h := nqp::getattr(%_,Map,'$!storage')), + nqp::create(self)!SET-SELF( + nqp::ifnull(nqp::atkey(h,'year'), $!year), + nqp::ifnull(nqp::atkey(h,'month'), $!month), + nqp::ifnull(nqp::atkey(h,'day'), $!day), + nqp::ifnull(nqp::atkey(h,'hour'), $!hour), + nqp::ifnull(nqp::atkey(h,'minute'), $!minute), + nqp::ifnull(nqp::atkey(h,'second'), $!second), + nqp::ifnull(nqp::atkey(h,'timezone'),$!timezone), + &!formatter, + ) + ), + self.clone(|%_) ) } @@ -278,12 +280,21 @@ method hh-mm-ss() { sprintf "%02d:%02d:%02d", $!hour,$!minute,$!second } method later(:$earlier, *%unit) { - my @pairs = %unit.pairs; - die "More than one time unit supplied" if @pairs > 1; - die "No time unit supplied" unless @pairs; - my $unit = self!VALID-UNIT(@pairs.AT-POS(0).key); - my $amount = @pairs.AT-POS(0).value; + # basic sanity check + nqp::if( + nqp::eqaddr( + (my \later := (my \iterator := %unit.iterator).pull-one), + IterationEnd + ), + (die "No time unit supplied"), + nqp::unless( + nqp::eqaddr(iterator.pull-one,IterationEnd), + (die "More than one time unit supplied") + ) + ); + my $unit := later.key; + my $amount = later.value; $amount = -$amount if $earlier; # work on instant (tai) diff -Nru rakudo-2018.10/src/core/Deprecations.pm6 rakudo-2018.12/src/core/Deprecations.pm6 --- rakudo-2018.10/src/core/Deprecations.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Deprecations.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -74,9 +74,10 @@ $index = $_ with $bt.next-interesting-index($index, :noproto); } else { - $index = $_ - with $bt.next-interesting-index($index, :noproto, :setting) - for ^$up; + for ^$up -> $level { + $index = $_ + with $bt.next-interesting-index($index, :noproto, :setting) + } } my $callsite = $bt[$index]; diff -Nru rakudo-2018.10/src/core/Distribution.pm6 rakudo-2018.12/src/core/Distribution.pm6 --- rakudo-2018.10/src/core/Distribution.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Distribution.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -78,7 +78,8 @@ role Distribution::Locally does Distribution { has IO::Path $.prefix; method content($address) { - my $handle = IO::Handle.new: path => IO::Path.new($address, :CWD($!prefix // $*CWD)); + my $path = IO::Path.new($.meta{$address} // $address, :CWD($!prefix.absolute // $*CWD.absolute)); + my $handle = IO::Handle.new(:$path); $handle // $handle.throw; } } diff -Nru rakudo-2018.10/src/core/Exception.pm6 rakudo-2018.12/src/core/Exception.pm6 --- rakudo-2018.10/src/core/Exception.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Exception.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -2328,9 +2328,11 @@ my class X::Assignment::RO is Exception { has $.value = "value"; method message { - "Cannot modify an immutable {$!value.^name} ({ - Rakudo::Internals.SHORT-GIST: $!value - })" + nqp::isconcrete($!value) + ?? "Cannot modify an immutable {$!value.^name} ({ + Rakudo::Internals.SHORT-GIST: $!value + })" + !! "Cannot modify an immutable '{$!value.^name}' type object" } method typename { $.value.^name } } @@ -2628,7 +2630,7 @@ if $.capture { for $.capture.list { try @bits.push( - $where ?? Rakudo::Internals.SHORT-GIST($_) !! .WHAT.perl + $where ?? Rakudo::Internals.SHORT-GIST($_) !! .WHAT.perl ~ ':' ~ (.defined ?? "D" !! "U") ); @bits.push($_.^name) if $!; when Failure { @@ -2944,13 +2946,16 @@ } } -my class X::Assignment::ArrayShapeMismatch is Exception { +my class X::ArrayShapeMismatch is Exception { + has $.action = "assign"; has $.target-shape; has $.source-shape; method message() { "Cannot assign an array of shape $.source-shape to an array of shape $.target-shape" } } +my class X::Assignment::ArrayShapeMismatch is X::ArrayShapeMismatch { +} my class X::Assignment::ToShaped is Exception { has $.shape; @@ -2965,6 +2970,11 @@ "No compiler available for Perl $.version" } } +my class X::Language::TooLate is Exception { + method message() { + "Too late to switch language version. Must be used as the very first statement." + } +} my class X::Proc::Unsuccessful is Exception { has $.proc; diff -Nru rakudo-2018.10/src/core/Hash.pm6 rakudo-2018.12/src/core/Hash.pm6 --- rakudo-2018.10/src/core/Hash.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Hash.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -71,7 +71,9 @@ ) ) } - method STORE(Hash:D: \to_store) { + + proto method STORE(|) {*} + multi method STORE(Hash:D: \to_store) { my $temp := nqp::p6bindattrinvres( nqp::clone(self), # make sure we get a possible descriptor as well Map, @@ -111,6 +113,16 @@ nqp::p6bindattrinvres(self,Map,'$!storage',$storage) } + multi method STORE(Hash:D: \keys, \values) { + my \iterkeys := keys.iterator; + my \itervalues := values.iterator; + nqp::bindattr(self,Map,'$!storage',nqp::hash); + nqp::until( + nqp::eqaddr((my \key := iterkeys.pull-one),IterationEnd), + self.STORE_AT_KEY(key,itervalues.pull-one) + ); + self + } multi method ASSIGN-KEY(Hash:D: Str:D $key, Mu \assignval) is raw { my \storage := nqp::getattr(self,Map,'$!storage'); @@ -619,7 +631,7 @@ method keys() { Seq.new(Keys.new(self)) } my class Values does Rakudo::Iterator::Mappy { - method pull-one() { + method pull-one() is raw { nqp::if( $!iter, nqp::getattr(nqp::iterval(nqp::shift($!iter)), diff -Nru rakudo-2018.10/src/core/hash_slice.pm6 rakudo-2018.12/src/core/hash_slice.pm6 --- rakudo-2018.10/src/core/hash_slice.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/hash_slice.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -49,12 +49,24 @@ multi sub postcircumfix:<{ }>( \SELF, Iterable \key ) is raw { nqp::iscont(key) ?? SELF.AT-KEY(key) - !! key.flatmap({ SELF{$_} }).eager.list; + !! nqp::p6bindattrinvres(nqp::create(List),List,'$!reified', + nqp::stmts( + Rakudo::Iterator.AssociativeIterableKeys(SELF,key) + .push-all(my \buffer := nqp::create(IterationBuffer)), + buffer + ) + ) } multi sub postcircumfix:<{ }>(\SELF, Iterable \key, Mu \ASSIGN) is raw { nqp::iscont(key) ?? SELF.ASSIGN-KEY(key, ASSIGN) - !! (key.flatmap({ SELF{$_} }).eager.list = ASSIGN) + !! (nqp::p6bindattrinvres(nqp::create(List),List,'$!reified', + nqp::stmts( + Rakudo::Iterator.AssociativeIterableKeys(SELF //= {},key) + .push-all(my \buffer := nqp::create(IterationBuffer)), + buffer + ) + ) = ASSIGN) } multi sub postcircumfix:<{ }>(\SELF, Iterable \key, :$BIND!) is raw { X::Bind::Slice.new(type => SELF.WHAT).throw; diff -Nru rakudo-2018.10/src/core/Hyper.pm6 rakudo-2018.12/src/core/Hyper.pm6 --- rakudo-2018.10/src/core/Hyper.pm6 1970-01-01 00:00:00.000000000 +0000 +++ rakudo-2018.12/src/core/Hyper.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -0,0 +1,451 @@ +# A class to perform hyper operations of the form left op right + +class Hyper { + has $.operator; # for some reason we cant make this a &.operator + has int8 $.dwim-left; # left side wont end + has int8 $.dwim-right; # right side wont end + has int8 $.assigns; # assigns to left side + + method new(\op, Bool() :$dwim-left, Bool() :$dwim-right) { + self.bless( + :operator(op), + :$dwim-left, + :$dwim-right, + :assigns(op.name.ends-with(' + {assigning}')), + ) + } + + # for error messages + method name() { + my str $name = $!operator.name || 'infix:'; + my int $start = nqp::index($name,"«"); + $start = nqp::index($name,"<") if $start == -1; + my int $end = nqp::index($name,"»"); + $end = nqp::index($name,">") if $end == -1; + + ($!dwim-left ?? '<<' !! '>>') + ~ nqp::substr($name,$start + 1,$end - $start -1) + ~ ($!dwim-right ?? '>>' !! '<<') + } + + proto method infix(|) {*} + + # x >>op<< y + multi method infix(\left, \right) is raw { $!operator(left,right) } + + # %x >>op<< %y + multi method infix( + Associative:D \left, + Associative:D \right + --> Associative:D + ) is default { + nqp::istype(left,Pair) + ?? nqp::istype(right,Pair) + ?? self!pair-pair(left,right) + !! self!pair-mu(left,right) + !! nqp::istype(right,Pair) + ?? self!mu-pair(left,right) + !! nqp::eqaddr(left.keyof,Str(Any)) + && nqp::eqaddr(right.keyof,Str(Any)) + ?? self!str-associatives(left,right) + !! self!obj-associatives(left,right) + } + + # %x >>op<< ... + multi method infix(Associative:D \left, List:D \right) { + die "{left.^name} $.name {right.^name} can never work reliably: order of keys in {left.^name} is indeterminate" + } + + # %x >>op<< y + multi method infix(Associative:D \left, \right --> Associative:D) { + return self!pair-mu(left,right) if nqp::istype(left,Pair); + + if $!assigns { + self.infix(left.values,right); + left + } + else { + my \result := nqp::create(left.WHAT).STORE( + left.keys, + self.infix(left.values,right), + :INITIALIZE + ); + nqp::iscont(left) ?? result.item !! result; + } + } + + # ... >>op<< %y + multi method infix(List:D \left, Associative:D \right) { + die "{left.^name} $.name {right.^name} can never work reliably: order of keys in {right.^name} is indeterminate" + } + + # x >>op<< %y + multi method infix(\left, Associative:D \right --> Associative:D) { + return self!mu-pair(left,right) if nqp::istype(right,Pair); + + my \result := nqp::create(right.WHAT).STORE( + right.keys, + self.infix(left,right.values), + :INITIALIZE + ); + nqp::iscont(right) ?? result.item !! result; + } + + # [x] >>op<< y + multi method infix(Positional:D \left, \right --> Positional:D) { + X::HyperOp::Infinite.new(:side, :$!operator).throw + if left.is-lazy; + + my int $left-elems = left.elems; + X::HyperOp::NonDWIM.new( + :$!operator, :$left-elems, :right-elems(1), :recursing + ).throw + unless $left-elems == 1 + or $left-elems > 1 and $!dwim-right + or $left-elems == 0 and $!dwim-left || $!dwim-right; + + my \iterator := left.iterator; + if $!assigns { + nqp::until( + nqp::eqaddr((my \value := iterator.pull-one),IterationEnd), + self.infix(value,right) + ); + left + } + else { + my \values := nqp::create(IterationBuffer); + nqp::until( + nqp::eqaddr((my \value := iterator.pull-one),IterationEnd), + nqp::push(values, self.infix(value,right)) + ); + + my \result := nqp::eqaddr(left.WHAT,List) + || nqp::eqaddr(left.WHAT,Slip) + ?? nqp::p6bindattrinvres( + nqp::create(left),List,'$!reified',values + ) + !! nqp::can(left,"STORE") + ?? left.WHAT.new(nqp::p6bindattrinvres( + nqp::create(List),List,'$!reified',values + )) + !! nqp::p6bindattrinvres( + nqp::create(List),List,'$!reified',values + ); + nqp::iscont(left) ?? result.item !! result + } + } + + # x >>op<< [y] + multi method infix(\left, Positional:D \right --> Positional:D) { + X::HyperOp::Infinite.new(:side, :$!operator).throw + if right.is-lazy; + + my int $right-elems = right.elems; + X::HyperOp::NonDWIM.new( + :$!operator, :left-elems(1), :$right-elems, :recursing + ).throw + unless $right-elems == 1 + or $right-elems > 1 and $!dwim-left + or $right-elems == 0 and $!dwim-left || $!dwim-right; + + my \values := nqp::create(IterationBuffer); + my \iterator := right.iterator; + + nqp::until( + nqp::eqaddr((my \value := iterator.pull-one),IterationEnd), + nqp::push(values, self.infix(left,value)) + ); + + my \result := nqp::eqaddr(right.WHAT,List) + || nqp::eqaddr(right.WHAT,Slip) + ?? nqp::p6bindattrinvres( # List or Slip + nqp::create(right),List,'$!reified',values + ) + !! nqp::can(right,"STORE") + ?? right.WHAT.new(nqp::p6bindattrinvres( + nqp::create(List),List,'$!reified',values + )) + !! nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',values); + nqp::iscont(right) ?? result.item !! result + } + + # ... >>op<< ... + multi method infix( + Iterable:D \left, + Iterable:D \right + --> Iterable:D + ) { + my \left-iterator = left.iterator; + my \right-iterator = right.iterator; + + # Check whether any side is lazy. They must not be to proceed. + if left-iterator.is-lazy { + X::HyperOp::Infinite.new(:side, :$!operator).throw + if right-iterator.is-lazy; + X::HyperOp::Infinite.new(:side, :$!operator).throw + if nqp::not_i($!dwim-left) || $!dwim-right; + } + X::HyperOp::Infinite.new(:side, :$!operator).throw + if right-iterator.is-lazy + and (nqp::not_i($!dwim-right) || $!dwim-left); + + my \values := + $!dwim-left + ?? $!dwim-right + ?? self!iterators-left-right(left-iterator,right-iterator) + !! self!iterators-left(left-iterator,right-iterator) + !! $!dwim-right + ?? self!iterators-right(left-iterator,right-iterator) + !! nqp::istype(left-iterator,PredictiveIterator) + && nqp::istype(right-iterator,PredictiveIterator) + ?? self!predictive-iterators(left-iterator,right-iterator) + !! self!iterators(left-iterator,right-iterator) + ; + my \result := nqp::p6bindattrinvres( + nqp::create( + nqp::istype(left,List) ?? left.WHAT !! List # keep subtype + ), + List, '$!reified', values + ); + nqp::iscont(left) ?? result.item !! result; + } + + # :x >>op<< y + method !pair-mu(\left,\right) { +# multi method infix(Pair:D \left, \right) { + nqp::p6bindattrinvres( + nqp::clone(left), + Pair, + '$!value', + self.infix(nqp::getattr(left,Pair,'$!value'), right) + ) + } + + # x >>op<< :y + method !mu-pair(\left,\right) { +# multi method infix(\left, Pair:D \right) { + nqp::p6bindattrinvres( + nqp::clone(right), + Pair, + '$!value', + self.infix(left, nqp::getattr(right,Pair,'$!value')) + ) + } + + # :x >>op<< :y + method !pair-pair(\left, \right) { +# multi method infix(Pair:D \left, Pair:D \right) { + nqp::if( + nqp::getattr(left,Pair,'$!key').WHICH + eq nqp::getattr(right,Pair,'$!key').WHICH, + nqp::p6bindattrinvres( + nqp::clone(left),Pair,'$!value',self.infix( + nqp::getattr(left, Pair,'$!value'), + nqp::getattr(right,Pair,'$!value') + ) + ), + Nil + ) + } + + # using an infix on a one element list in a meta op + multi method infix(\object) { + nqp::if( + nqp::can($!operator,"nodal"), + nodemap($!operator,object), + deepmap($!operator,object) + ) + } + +#--- Private helper methods ---------------------------------------------------- + + # ... >>op<< ... + method !predictive-iterators( + PredictiveIterator:D \left, + PredictiveIterator:D \right, + ) { + X::HyperOp::NonDWIM.new( + :$!operator, + :left-elems(left.count-only), + :right-elems(right.count-only), + :recursing + ).throw + if left.count-only != right.count-only; + + # sure they have same number of elems, so only need to check one + my \result := nqp::create(IterationBuffer); + nqp::until( + nqp::eqaddr((my \leftv := left.pull-one),IterationEnd), + nqp::push(result,self.infix(leftv,right.pull-one)) + ); + result + } + + # ... >>op<< ... + method !iterators(Iterator:D \left, Iterator:D \right) { + my \result := nqp::create(IterationBuffer); + + nqp::until( + nqp::eqaddr((my \leftv := left.pull-one),IterationEnd) + || nqp::eqaddr((my \rightv := right.pull-one),IterationEnd), + nqp::push(result, self.infix(leftv, rightv)) + ); + + nqp::if( + nqp::eqaddr(rightv,IterationEnd), + self!right-exhausted(left,nqp::elems(result)), + nqp::unless( + nqp::eqaddr(right.pull-one,IterationEnd), + self!left-exhausted(right,nqp::elems(result)) + ) + ); + + result + } + + # ... <>op>> ... + method !iterators-right(Iterator:D \left, Iterator:D \right) { + my \righti := Rakudo::Iterator.DWIM(right); + my \result := nqp::create(IterationBuffer); + + my \rightv := righti.pull-one; + nqp::unless( + righti.ended, + nqp::until( + nqp::eqaddr((my \leftv := left.pull-one),IterationEnd), + nqp::stmts( + nqp::push(result, self.infix(leftv,rightv)), + nqp::bind(rightv,righti.pull-one) + ) + ) + ); + + result + } + + # ... <> ... + method !iterators-left-right(Iterator:D \left, Iterator:D \right) { + my \lefti := Rakudo::Iterator.DWIM(left); + my \righti := Rakudo::Iterator.DWIM(right); + my \result := nqp::create(IterationBuffer); + + my \leftv := lefti.pull-one; + my \rightv := righti.pull-one; + nqp::unless( + lefti.ended || righti.ended, + nqp::until( + lefti.ended && righti.ended, + nqp::stmts( + nqp::push(result,self.infix(leftv,rightv)), + nqp::bind(leftv, lefti.pull-one), + nqp::bind(rightv,righti.pull-one) + ) + ) + ); + + result + } + + # handle normal hashes + method !str-associatives(\left, \right) { + my $keys := nqp::hash; + if $!dwim-left { + nqp::bindkey($keys,$_,1) if right.EXISTS-KEY($_) for left.keys; + } + else { + nqp::bindkey($keys,$_,1) for left.keys; + } + if nqp::not_i($!dwim-right) { + nqp::bindkey($keys,$_,1) for right.keys; + } + + # create HLL version of keys + my @keys is List = + nqp::p6bindattrinvres(nqp::create(Map),Map,'$!storage',$keys).keys; + self!associatives(@keys, left, right) + } + + # handle object hashes / QuantHashes + method !obj-associatives(\left, \right) { + my $keys := nqp::hash; + if $!dwim-left { + nqp::bindkey($keys,.WHICH,$_) if right.EXISTS-KEY($_) for left.keys; + } + else { + nqp::bindkey($keys,.WHICH,$_) for left.keys; + } + if nqp::not_i($!dwim-right) { + nqp::bindkey($keys,.WHICH,$_) for right.keys; + } + + # create HLL version of keys + my @keys is List = + nqp::p6bindattrinvres(nqp::create(Map),Map,'$!storage',$keys).values; + self!associatives(@keys, left, right) + } + + # actually handle 2 associatives + method !associatives(@keys, \left, \right) { + my \values := nqp::p6bindattrinvres( + nqp::create(List),List,'$!reified', + quietly self!iterators( + Rakudo::Iterator.AssociativeIterableKeys(left, @keys), + Rakudo::Iterator.AssociativeIterableKeys(right,@keys), + ) + ); + if $!assigns { + left + } + else { + my \result := + nqp::create(left.WHAT).STORE(@keys, values, :INITIALIZE); + nqp::iscont(left) ?? result.item !! result + } + } + + # error when left side of non-DWIM exhausted + method !left-exhausted(Iterator:D \iterator, int $left-elems) { + my int $right-elems = $left-elems + 1; + nqp::until( + nqp::eqaddr(iterator.pull-one,IterationEnd), + ++$right-elems + ); + X::HyperOp::NonDWIM.new( + :$!operator, :$left-elems, :$right-elems, :recursing + ).throw; + } + + # error when right side of non-DWIM exhausted + method !right-exhausted(Iterator:D \iterator, int $right-elems) { + my int $left-elems = $right-elems + 1; + nqp::until( + nqp::eqaddr(iterator.pull-one,IterationEnd), + ++$left-elems + ); + X::HyperOp::NonDWIM.new( + :$!operator, :$left-elems, :$right-elems, :recursing + ).throw; + } +} + +# vim: ft=perl6 expandtab sw=4 diff -Nru rakudo-2018.10/src/core/HyperSeq.pm6 rakudo-2018.12/src/core/HyperSeq.pm6 --- rakudo-2018.10/src/core/HyperSeq.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/HyperSeq.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -34,7 +34,7 @@ RaceSeq.new(:$!configuration, :$!work-stage-head) } - method is-lazy() { False } + method is-lazy(--> False) { } multi method serial(HyperSeq:D:) { self.Seq } diff -Nru rakudo-2018.10/src/core/Int.pm6 rakudo-2018.12/src/core/Int.pm6 --- rakudo-2018.10/src/core/Int.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Int.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -294,6 +294,15 @@ nqp::mul_i($a, $b); } +multi sub infix:(Int:D $a, Int:D $b --> Bool:D) { + nqp::hllbool( # need to check types as enums such as Bool wind up here + nqp::eqaddr($a.WHAT,$b.WHAT) && nqp::iseq_I($a,$b) + ) +} +multi sub infix:(int $a, int $b --> Bool:D) { + nqp::hllbool(nqp::iseq_i($a,$b)) +} + multi sub infix:
(Int:D \a, Int:D \b) { b ?? nqp::div_I(nqp::decont(a), nqp::decont(b), Int) @@ -361,10 +370,10 @@ nqp::gcd_i($a, $b) } -multi sub infix:<===>(Int:D \a, Int:D \b) { +multi sub infix:<===>(Int:D $a, Int:D $b) { nqp::hllbool( - nqp::eqaddr(a.WHAT,b.WHAT) - && nqp::iseq_I(nqp::decont(a), nqp::decont(b)) + nqp::eqaddr($a.WHAT,$b.WHAT) + && nqp::iseq_I($a, $b) ) } multi sub infix:<===>(int $a, int $b) { diff -Nru rakudo-2018.10/src/core/IO/Notification.pm6 rakudo-2018.12/src/core/IO/Notification.pm6 --- rakudo-2018.10/src/core/IO/Notification.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/IO/Notification.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -26,7 +26,7 @@ } else { my $event = rename ?? FileRenamed !! FileChanged; - my $full-path = $is-dir ?? $*SPEC.catdir($path, path) !! $path; + my $full-path = ( $is-dir and path ) ?? $*SPEC.catdir($path, path) !! $path; $s.emit(Change.new(:path($full-path), :$event)); } }, diff -Nru rakudo-2018.10/src/core/IO/Path.pm6 rakudo-2018.12/src/core/IO/Path.pm6 --- rakudo-2018.10/src/core/IO/Path.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/IO/Path.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -283,8 +283,9 @@ if nqp::iseq_s($part, $up) { next unless $res-list; nqp::pop_s($res-list); - $resolved = $res-list ?? $sep ~ nqp::join($sep, $res-list) - !! $empty; + $resolved = $res-list + ?? nqp::concat(nqp::concat($volume, $sep), nqp::join($sep, $res-list)) + !! $empty; next; } diff -Nru rakudo-2018.10/src/core/IO/Socket/Async.pm6 rakudo-2018.12/src/core/IO/Socket/Async.pm6 --- rakudo-2018.10/src/core/IO/Socket/Async.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/IO/Socket/Async.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -8,11 +8,13 @@ has $!close-promise; has $!close-vow; + subset Port-Number of Int where { !defined($_) or $_ ~~ ^65536 }; + has Str $.peer-host; - has Int $.peer-port; + has Port-Number $.peer-port; has Str $.socket-host; - has Int $.socket-port; + has Port-Number $.socket-port; method new() { die "Cannot create an asynchronous socket directly; please use\n" ~ @@ -165,7 +167,7 @@ $!close-vow.keep(True); } - method connect(IO::Socket::Async:U: Str() $host, Int() $port, + method connect(IO::Socket::Async:U: Str() $host, Int() $port where Port-Number, :$enc = 'utf-8', :$scheduler = $*SCHEDULER) { my $p = Promise.new; my $v = $p.vow; @@ -196,11 +198,18 @@ } class ListenSocket is Tap { + has Promise $!VMIO-tobe; has Promise $.socket-host; has Promise $.socket-port; - method new(&on-close, Promise :$socket-host, Promise :$socket-port) { - self.bless(:&on-close, :$socket-host, :$socket-port); + submethod TWEAK(Promise :$!VMIO-tobe, Promise :$!socket-host, Promise :$!socket-port) { } + + method new(&on-close, Promise :$VMIO-tobe, Promise :$socket-host, Promise :$socket-port) { + self.bless(:&on-close, :$VMIO-tobe, :$socket-host, :$socket-port); + } + + method native-descriptor(--> Int) { + nqp::filenofh(await $!VMIO-tobe) } } @@ -221,15 +230,17 @@ my $lock := Lock::Async.new; my $tap; my int $finished = 0; + my Promise $VMIO-tobe .= new; my Promise $socket-host .= new; my Promise $socket-port .= new; + my $VMIO-vow = $VMIO-tobe.vow; my $host-vow = $socket-host.vow; my $port-vow = $socket-port.vow; $lock.protect: { my $cancellation := nqp::asynclisten( $!scheduler.queue(:hint-affinity), - -> Mu \socket, Mu \err, Mu \peer-host, Mu \peer-port, - Mu \socket-host, Mu \socket-port { + -> Mu \client-socket, Mu \err, Mu \peer-host, Mu \peer-port, + Mu \server-socket, Mu \socket-host, Mu \socket-port { $lock.protect: { if $finished { # do nothing @@ -241,10 +252,10 @@ $port-vow.break($exc) unless $port-vow.promise; $finished = 1; } - elsif socket { + elsif client-socket { my $client_socket := nqp::create(IO::Socket::Async); nqp::bindattr($client_socket, IO::Socket::Async, - '$!VMIO', socket); + '$!VMIO', client-socket); nqp::bindattr($client_socket, IO::Socket::Async, '$!enc', $!encoding.name); nqp::bindattr($client_socket, IO::Socket::Async, @@ -260,7 +271,8 @@ setup-close($client_socket); emit($client_socket); } - elsif socket-host { + elsif server-socket { + $VMIO-vow.keep(server-socket); $host-vow.keep(~socket-host); $port-vow.keep(+socket-port); } @@ -272,12 +284,12 @@ my $v = $p.vow; nqp::cancelnotify($cancellation, $!scheduler.queue, { $v.keep(True); }); $p - }, :$socket-host, :$socket-port; + }, :$VMIO-tobe, :$socket-host, :$socket-port; tap($tap); CATCH { default { tap($tap = ListenSocket.new({ Nil }, - :$socket-host, :$socket-port)) unless $tap; + :$VMIO-tobe, :$socket-host, :$socket-port)) unless $tap; quit($_); } } @@ -290,13 +302,17 @@ method serial(--> True) { } } - method listen(IO::Socket::Async:U: Str() $host, Int() $port, Int() $backlog = 128, - :$enc = 'utf-8', :$scheduler = $*SCHEDULER) { + method listen(IO::Socket::Async:U: Str() $host, Int() $port where Port-Number, + Int() $backlog = 128, :$enc = 'utf-8', :$scheduler = $*SCHEDULER) { my $encoding = Encoding::Registry.find($enc); Supply.new: SocketListenerTappable.new: :$host, :$port, :$backlog, :$encoding, :$scheduler } + method native-descriptor(--> Int) { + nqp::filenofh($!VMIO) + } + sub setup-close(\socket --> Nil) { my $p := Promise.new; nqp::bindattr(socket, IO::Socket::Async, '$!close-promise', $p); @@ -329,8 +345,8 @@ await $p } - method bind-udp(IO::Socket::Async:U: Str() $host, Int() $port, :$broadcast, - :$enc = 'utf-8', :$scheduler = $*SCHEDULER) { + method bind-udp(IO::Socket::Async:U: Str() $host, Int() $port where Port-Number, + :$broadcast, :$enc = 'utf-8', :$scheduler = $*SCHEDULER) { my $p = Promise.new; my $encoding = Encoding::Registry.find($enc); nqp::asyncudp( @@ -355,11 +371,13 @@ await $p } - method print-to(IO::Socket::Async:D: Str() $host, Int() $port, Str() $str, :$scheduler = $*SCHEDULER) { + method print-to(IO::Socket::Async:D: Str() $host, Int() $port where Port-Number, + Str() $str, :$scheduler = $*SCHEDULER) { self.write-to($host, $port, $!encoder.encode-chars($str), :$scheduler) } - method write-to(IO::Socket::Async:D: Str() $host, Int() $port, Blob $b, :$scheduler = $*SCHEDULER) { + method write-to(IO::Socket::Async:D: Str() $host, Int() $port where Port-Number, + Blob $b, :$scheduler = $*SCHEDULER) { my $p = Promise.new; my $v = $p.vow; nqp::asyncwritebytesto( diff -Nru rakudo-2018.10/src/core/Iterable.pm6 rakudo-2018.12/src/core/Iterable.pm6 --- rakudo-2018.10/src/core/Iterable.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Iterable.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -100,7 +100,7 @@ $!iterator.push-exactly($target, $n); } - method is-lazy() { True } + method is-lazy(--> True) { } } method lazy() { # Return a Seq with an iterator wrapping this Iterable, claiming to diff -Nru rakudo-2018.10/src/core/Kernel.pm6 rakudo-2018.12/src/core/Kernel.pm6 --- rakudo-2018.10/src/core/Kernel.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Kernel.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -184,6 +184,18 @@ + nqp::atpos_i(@rusage, nqp::const::RUSAGE_STIME_SEC) * 1000000 + nqp::atpos_i(@rusage, nqp::const::RUSAGE_STIME_MSEC) } + + my $endian := nqp::null; + method endian(--> Endian:D) { + nqp::ifnull( + $endian, + nqp::bind($endian,nqp::if( + blob8.new(0,1).read-int16(0) == 1, # hacky way to find out + BigEndian, + LittleEndian + )) + ) + } } Rakudo::Internals.REGISTER-DYNAMIC: '$*KERNEL', { diff -Nru rakudo-2018.10/src/core/List.pm6 rakudo-2018.12/src/core/List.pm6 --- rakudo-2018.10/src/core/List.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/List.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -673,7 +673,7 @@ ) } - multi method ACCEPTS(List:D: Iterable:U) { True } + multi method ACCEPTS(List:D: Iterable:U --> True) { } multi method ACCEPTS(List:D: Iterable:D $topic) { CATCH { default { return False } } # .elems on lazies throws return True if nqp::eqaddr(self, nqp::decont($topic)); diff -Nru rakudo-2018.10/src/core/Map.pm6 rakudo-2018.12/src/core/Map.pm6 --- rakudo-2018.10/src/core/Map.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Map.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -16,25 +16,25 @@ nqp::join( '|', nqp::stmts( # cannot use native str arrays early in setting - (my $keys := nqp::list_s), + (my \keys := nqp::list_s), (my \iter := nqp::iterator($!storage)), nqp::while( iter, - nqp::push_s($keys,nqp::iterkey_s(nqp::shift(iter))) + nqp::push_s(keys,nqp::iterkey_s(nqp::shift(iter))) ), - (my $sorted := Rakudo::Sorting.MERGESORT-str($keys)), + (my \sorted := Rakudo::Sorting.MERGESORT-str(keys)), (my int $i = -1), - (my int $elems = nqp::elems($sorted)), - (my $strings := nqp::list_s), + (my int $elems = nqp::elems(sorted)), + (my \strings := nqp::list_s), nqp::while( nqp::islt_i(($i = nqp::add_i($i,1)),$elems), nqp::stmts( - (my $key := nqp::atpos_s($sorted,$i)), - nqp::push_s($strings,$key), - nqp::push_s($strings,nqp::atkey($!storage,$key).perl) + (my \key := nqp::atpos_s(sorted,$i)), + nqp::push_s(strings,key), + nqp::push_s(strings,nqp::atkey($!storage,key).WHICH) ) ), - $strings + strings ) ) ) @@ -412,6 +412,20 @@ ) ) } + multi method STORE(Map:D: \keys, \values, :$INITIALIZE!) { + my \iterkeys := keys.iterator; + my \itervalues := values.iterator; + my \storage := $!storage := nqp::hash; + nqp::until( + nqp::eqaddr((my \key := iterkeys.pull-one),IterationEnd), + nqp::bindkey( + storage, + nqp::if(nqp::istype(key,Str),key,key.Str), + nqp::decont(itervalues.pull-one) + ) + ); + self + } multi method STORE(Map:D: |) { X::Assignment::RO.new(value => self).throw } method Capture(Map:D:) { diff -Nru rakudo-2018.10/src/core/Match.pm6 rakudo-2018.12/src/core/Match.pm6 --- rakudo-2018.10/src/core/Match.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Match.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -25,11 +25,12 @@ } method !MATCH() { - my int $from = nqp::getattr_i(self, Match, '$!from'); - my int $pos = nqp::getattr_i(self, Match, '$!pos'); - my Mu $list; + my Mu $list := Nil; my Mu $hash := nqp::hash(); - if nqp::isge_i($pos, $from) { + if nqp::isge_i( + nqp::getattr_i(self,Match,'$!pos'), + nqp::getattr_i(self, Match, '$!from') + ) { # For captures with lists, initialize the lists. my $caplist := $NO_CAPS; my $rxsub := nqp::getattr(self, Match, '$!regexsub'); @@ -45,14 +46,14 @@ $namecount = nqp::add_i($namecount, 1); if nqp::iterval(nqp::shift($iter)) >= 2 { $name = nqp::iterkey_s($iter); - $onlyname = $name if nqp::iseq_i($namecount, 1); nqp::iscclass(nqp::const::CCLASS_NUMERIC, $name, 0) ?? nqp::bindpos( nqp::if(nqp::isconcrete($list), $list, ($list := nqp::list())), - nqp::fromstr_I($name, Int), []) - !! nqp::bindkey($hash, $name, []); + nqp::fromstr_I($name, Int), nqp::create(Array)) + !! nqp::bindkey($hash, $name, nqp::create(Array)); } } + $onlyname = $name if nqp::iseq_i($namecount, 1); } } @@ -66,10 +67,9 @@ # If there's only one destination, avoid repeated hash lookups my int $cselems = nqp::elems($cs); my int $csi = -1; - my Mu $dest; # numeric: <= ord("9") so positional capture - $dest := nqp::islt_i(nqp::ord($onlyname),58) + my Mu $dest := nqp::islt_i(nqp::ord($onlyname),58) ?? nqp::atpos($list, $onlyname) !! nqp::atkey($hash, $onlyname); @@ -719,8 +719,6 @@ } multi method INTERPOLATE_ASSERTION(Mu:D \var, int \im, int \monkey, $, $, \context) { - my \cur = self.'!cursor_start_cur'(); - # We are in a regex assertion, the strings we get will be # treated as regex rules. my $rx := MAKE_REGEX(var,im == 1 || im == 3,im == 2 || im == 3,monkey,context); @@ -729,9 +727,9 @@ match.Bool && nqp::isgt_i($len,-1) - && nqp::isle_i(nqp::add_i(nqp::getattr_i(cur, $?CLASS, '$!from'),$len),nqp::chars(cur.target)) + && nqp::isle_i(nqp::add_i(nqp::getattr_i(self, $?CLASS, '$!pos'),$len),nqp::chars(self.target)) ?? match - !! cur + !! self.'!cursor_start_fail'() } method CALL_SUBRULE($rule, |c) { @@ -857,7 +855,7 @@ } proto method Bool(|) {*} - multi method Bool(Match:U:) { False } + multi method Bool(Match:U: --> False) { } multi method Bool(Match:D:) { nqp::hllbool($!pos >= $!from) } multi method Numeric(Match:D:) { diff -Nru rakudo-2018.10/src/core/metaops.pm6 rakudo-2018.12/src/core/metaops.pm6 --- rakudo-2018.10/src/core/metaops.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/metaops.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1,6 +1,14 @@ sub METAOP_ASSIGN(\op) { - -> Mu \a, Mu \b { a = op.( ( a.DEFINITE ?? a !! op.() ), b) } + my \op-is := nqp::ifnull( + nqp::atkey( # is it a core op? + nqp::ifnull($CORE_METAOP_ASSIGN,Rakudo::Internals.INSTALL-CORE-METAOPS), + nqp::objectid(op) + ), + -> Mu \a, Mu \b { a = op.( ( a.DEFINITE ?? a !! op.() ), b) } + ); + op-is.set_name(op.name ~ ' + {assigning}'); # checked for in Hyper.new + op-is } sub METAOP_TEST_ASSIGN:(\lhs, $rhs) is raw { lhs // (lhs = $rhs()) } @@ -25,7 +33,7 @@ -> +lol { my $rop = lol.elems == 2 ?? op !! &reduce(op); my $laze = False; - my @loi = eager for lol -> \elem { + my @loi is List = eager for lol -> \elem { if nqp::iscont(elem) { $laze = False; (elem,).iterator @@ -86,7 +94,7 @@ my $arity = lol.elems; my $rop = $arity == 2 ?? op !! &reduce(op); my $laze = True; - my @loi = eager for lol -> \elem { + my @loi is List = eager for lol -> \elem { if nqp::iscont(elem) { $laze = False; Rakudo::Iterator.OneValue(elem) @@ -522,121 +530,8 @@ sub METAOP_HYPER_CALL(\list, |args) { deepmap(-> $c { $c(|args) }, list) } -proto sub HYPER(|) {*} - -multi sub HYPER(&op, \left, \right, :$dwim-left, :$dwim-right) { - op(left, right); -} - -multi sub HYPER(&op, Associative:D \left, Associative:D \right, :$dwim-left, :$dwim-right) { - my %keyset; - if !$dwim-left { - %keyset{$_} = 1 for left.keys; - } - else { - %keyset{$_} = 1 if right.EXISTS-KEY($_) for left.keys; - } - if !$dwim-right { - %keyset{$_} = 1 for right.keys; - } - my @keys = %keyset.keys; - my $type = left.WHAT; - my \result := $type.new; - result = quietly @keys Z=> HYPER(&op, left{@keys}, right{@keys}, :$dwim-left, :$dwim-right); - nqp::iscont(left) ?? result.item !! result; -} - -multi sub HYPER(&op, Associative:D \left, \right, :$dwim-left, :$dwim-right) { - my @keys = left.keys; - my $type = left.WHAT; - my \result := $type.new; - result = @keys Z=> HYPER(&op, left{@keys}, right, :$dwim-left, :$dwim-right); - nqp::iscont(left) ?? result.item !! result; -} - -multi sub HYPER(&op, \left, Associative:D \right, :$dwim-left, :$dwim-right) { - my @keys = right.keys; - my $type = right.WHAT; - my \result := $type.new; - result = @keys Z=> HYPER(&op, left, right{@keys}, :$dwim-left, :$dwim-right); - nqp::iscont(right) ?? result.item !! result; -} - -multi sub HYPER(&operator, Positional:D \left, \right, :$dwim-left, :$dwim-right) { - my @result; - X::HyperOp::Infinite.new(:side, :&operator).throw if left.is-lazy; - my int $elems = left.elems; - X::HyperOp::NonDWIM.new(:&operator, :left-elems($elems), :right-elems(1), :recursing(?(callframe(2).code andthen .name eq 'HYPER'))).throw - unless $elems == 1 or $elems > 1 and $dwim-right or $elems == 0 and $dwim-left || $dwim-right; - my \lefti := left.iterator; - my int $i = 0; - until nqp::eqaddr((my \value := lefti.pull-one),IterationEnd) { - @result[$i++] := HYPER(&operator, value, right, :$dwim-left, :$dwim-right); - } - # Coerce to the original type if it's a subtype of List - my $type = nqp::istype(left, List) ?? left.WHAT !! List; - nqp::iscont(left) ?? $type(|@result.eager).item !! $type(|@result.eager) -} - -multi sub HYPER(&operator, \left, Positional:D \right, :$dwim-left, :$dwim-right) { - my @result; - X::HyperOp::Infinite.new(:side, :&operator).throw if right.is-lazy; - my int $elems = right.elems; - X::HyperOp::NonDWIM.new(:&operator, :left-elems(1), :right-elems($elems), :recursing(?(callframe(3).code andthen .name eq 'HYPER'))).throw - unless $elems == 1 or $elems > 1 and $dwim-left or $elems == 0 and $dwim-left || $dwim-right; - my \righti := right.iterator; - my int $i = 0; - until nqp::eqaddr((my \value := righti.pull-one),IterationEnd) { - @result[$i++] := HYPER(&operator, left, value, :$dwim-left, :$dwim-right); - } - # Coerce to the original type if it's a subtype of List - my $type = nqp::istype(right, List) ?? right.WHAT !! List; - nqp::iscont(right) ?? $type(|@result.eager).item !! $type(|@result.eager) -} - -multi sub HYPER(&operator, Iterable:D \left, Iterable:D \right, :$dwim-left, :$dwim-right) { - my \left-iterator = left.iterator; - my \right-iterator = right.iterator; - - # Check whether any side is lazy. They must not be to proceed. - if left-iterator.is-lazy { - X::HyperOp::Infinite.new(:side, :&operator).throw if right-iterator.is-lazy; - X::HyperOp::Infinite.new(:side, :&operator).throw if not $dwim-left or $dwim-right; - } - X::HyperOp::Infinite.new(:side, :&operator).throw if right-iterator.is-lazy and - (not $dwim-right or $dwim-left); - - my \lefti := Rakudo::Iterator.DWIM(left-iterator); - my \righti := Rakudo::Iterator.DWIM(right-iterator); - - my \result := nqp::create(IterationBuffer); - loop { - my \leftv := lefti.pull-one; - my \rightv := righti.pull-one; - - X::HyperOp::NonDWIM.new(:&operator, :left-elems(lefti.count-elems), :right-elems(righti.count-elems), :recursing(?(callframe(3).code andthen .name eq 'HYPER'))).throw - if !$dwim-left and !$dwim-right and (lefti.ended != righti.ended); - - last if ($dwim-left and $dwim-right) ?? (lefti.ended and righti.ended) !! - (($dwim-left or lefti.ended) and ($dwim-right or righti.ended)); - last if $++ == 0 and ($dwim-left and lefti.ended or $dwim-right and righti.ended); - - nqp::push(result,HYPER(&operator, leftv, rightv, :$dwim-left, :$dwim-right)); - } - - # Coerce to the original type - my $type = nqp::istype(left, List) ?? left.WHAT !! List; # keep subtypes of List - my \retval = $type.new; - nqp::bindattr(retval, List, '$!reified', result); - nqp::iscont(left) ?? retval.item !! retval; -} - -multi sub HYPER(\op, \obj) { - nqp::if( - nqp::can(op,"nodal"), - nodemap(op, obj), - deepmap(op,obj) - ) +sub HYPER(\operator, :$dwim-left, :$dwim-right, |c) { + Hyper.new(operator, :$dwim-left, :$dwim-right).infix(|c) } proto sub deepmap($, $, *%) {*} diff -Nru rakudo-2018.10/src/core/MixHash.pm6 rakudo-2018.12/src/core/MixHash.pm6 --- rakudo-2018.10/src/core/MixHash.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/MixHash.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -15,6 +15,15 @@ ) ) } + multi method STORE(MixHash:D: \objects, \values --> MixHash:D) { + self.SET-SELF( + Rakudo::QuantHash.ADD-OBJECTS-VALUES-TO-MIX( + nqp::create(Rakudo::Internals::IterationSet), + objects.iterator, + values.iterator + ) + ) + } multi method AT-KEY(MixHash:D: \k) is raw { Proxy.new( FETCH => { @@ -184,12 +193,10 @@ ) } - # same as Baggy.values method push-all($target --> IterationEnd) { nqp::while( # doesn't sink $!iter, - $target.push(nqp::getattr( - nqp::iterval(nqp::shift($!iter)),Pair,'$!value')) + $target.push(proxy(nqp::shift($!iter),$!hash)) ) } } diff -Nru rakudo-2018.10/src/core/Mix.pm6 rakudo-2018.12/src/core/Mix.pm6 --- rakudo-2018.10/src/core/Mix.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Mix.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -11,6 +11,15 @@ !! self.SET-SELF(Rakudo::QuantHash.ADD-PAIRS-TO-MIX( nqp::create(Rakudo::Internals::IterationSet), $iterator)) } + multi method STORE(Mix:D: \objects, \values, :$INITIALIZE! --> Mix:D) { + self.SET-SELF( + Rakudo::QuantHash.ADD-OBJECTS-VALUES-TO-MIX( + nqp::create(Rakudo::Internals::IterationSet), + objects.iterator, + values.iterator + ) + ) + } multi method DELETE-KEY(Mix:D: \k) { X::Immutable.new(method => 'DELETE-KEY', typename => self.^name).throw; diff -Nru rakudo-2018.10/src/core/Mixy.pm6 rakudo-2018.12/src/core/Mixy.pm6 --- rakudo-2018.10/src/core/Mixy.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Mixy.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1,5 +1,7 @@ my role Mixy does Baggy { + method of() { Real } + multi method hash(Mixy:D: --> Hash:D) { self!HASHIFY(Real) } multi method Hash(Mixy:D: --> Hash:D) { self!HASHIFY(Any) } diff -Nru rakudo-2018.10/src/core/Mu.pm6 rakudo-2018.12/src/core/Mu.pm6 --- rakudo-2018.10/src/core/Mu.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Mu.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -964,11 +964,11 @@ multi sub infix:(Any:U \a, Any:U \b) { nqp::hllbool(nqp::eqaddr(nqp::decont(a),nqp::decont(b))) } -multi sub infix:(Any:D \a, Any:U \b) { False } -multi sub infix:(Any:U \a, Any:D \b) { False } +multi sub infix:(Any:D \a, Any:U \b --> False) { } +multi sub infix:(Any:U \a, Any:D \b --> False) { } multi sub infix:(Any:D \a, Any:D \b) { nqp::hllbool( - nqp::eqaddr(a,b) + nqp::eqaddr(nqp::decont(a),nqp::decont(b)) || (nqp::eqaddr(a.WHAT,b.WHAT) && nqp::iseq_s(a.perl,b.perl)) ) } diff -Nru rakudo-2018.10/src/core/native_array.pm6 rakudo-2018.12/src/core/native_array.pm6 --- rakudo-2018.10/src/core/native_array.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/native_array.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -35,6 +35,10 @@ multi method unshift(array:D: **@values) { self.unshift(@values) } multi method prepend(array:D: *@values) { self.unshift(@values) } + sub INDEX_OUT_OF_RANGE(Int:D $got --> Nil) { + X::OutOfRange.new(what => "Index", :$got, range => "0..^Inf").throw + } + sub EQV_DIMENSIONS(Mu \one, Mu \two) is raw { nqp::iseq_i( # much faster than one.shape eqv two.shape (my int $dims = nqp::elems( @@ -89,29 +93,41 @@ my role strarray[::T] does Positional[T] is array_type(T) { #- start of generated part of strarray role ----------------------------------- -#- Generated on 2018-09-15T11:00:21+02:00 by tools/build/makeNATIVE_ARRAY.p6 +#- Generated on 2018-12-12T18:28:48+01:00 by tools/build/makeNATIVE_ARRAY.p6 #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE - multi method AT-POS(strarray:D: int $idx) is raw { - nqp::atposref_s(self, $idx) - } - multi method AT-POS(strarray:D: Int:D $idx) is raw { - nqp::atposref_s(self, $idx) - } - - multi method ASSIGN-POS(strarray:D: int $idx, str $value) { - nqp::bindpos_s(self, $idx, $value) - } - multi method ASSIGN-POS(strarray:D: Int:D $idx, str $value) { - nqp::bindpos_s(self, $idx, $value) + multi method AT-POS(strarray:D: int $idx --> str) is raw { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::atposref_s(self,$idx) + } + multi method AT-POS(strarray:D: Int:D $idx --> str) is raw { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::atposref_s(self,$idx) + } + + multi method ASSIGN-POS(strarray:D: int $idx, str $value --> str) { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_s(self, $idx, $value) + } + multi method ASSIGN-POS(strarray:D: Int:D $idx, str $value --> str) { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_s(self, $idx, $value) + } + multi method ASSIGN-POS(strarray:D: int $idx, Str:D $value --> str) { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_s(self, $idx, $value) + } + multi method ASSIGN-POS(strarray:D: Int:D $idx, Str:D $value --> str) { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_s(self, $idx, $value) } - multi method ASSIGN-POS(strarray:D: int $idx, Str:D $value) { - nqp::bindpos_s(self, $idx, $value) - } - multi method ASSIGN-POS(strarray:D: Int:D $idx, Str:D $value) { - nqp::bindpos_s(self, $idx, $value) - } - multi method ASSIGN-POS(strarray:D: Any $idx, Mu \value) { + multi method ASSIGN-POS(strarray:D: Any $idx, Mu \value --> Nil) { X::TypeCheck.new( operation => "assignment to str array element #$idx", got => value, @@ -135,6 +151,7 @@ :action, :what(self.^name) ).throw, nqp::stmts( + nqp::setelems(self,0), $iterator.push-all(self), self ) @@ -174,7 +191,7 @@ nqp::push_s(self, $value); self } - multi method push(strarray:D: Mu \value) { + multi method push(strarray:D: Mu \value --> Nil) { X::TypeCheck.new( operation => 'push to str array', got => value, @@ -572,29 +589,41 @@ my role intarray[::T] does Positional[T] is array_type(T) { #- start of generated part of intarray role ----------------------------------- -#- Generated on 2018-09-15T11:00:21+02:00 by tools/build/makeNATIVE_ARRAY.p6 +#- Generated on 2018-12-12T18:28:48+01:00 by tools/build/makeNATIVE_ARRAY.p6 #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE - multi method AT-POS(intarray:D: int $idx) is raw { - nqp::atposref_i(self, $idx) - } - multi method AT-POS(intarray:D: Int:D $idx) is raw { - nqp::atposref_i(self, $idx) - } - - multi method ASSIGN-POS(intarray:D: int $idx, int $value) { - nqp::bindpos_i(self, $idx, $value) + multi method AT-POS(intarray:D: int $idx --> int) is raw { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::atposref_i(self,$idx) + } + multi method AT-POS(intarray:D: Int:D $idx --> int) is raw { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::atposref_i(self,$idx) + } + + multi method ASSIGN-POS(intarray:D: int $idx, int $value --> int) { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_i(self, $idx, $value) + } + multi method ASSIGN-POS(intarray:D: Int:D $idx, int $value --> int) { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_i(self, $idx, $value) + } + multi method ASSIGN-POS(intarray:D: int $idx, Int:D $value --> int) { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_i(self, $idx, $value) + } + multi method ASSIGN-POS(intarray:D: Int:D $idx, Int:D $value --> int) { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_i(self, $idx, $value) } - multi method ASSIGN-POS(intarray:D: Int:D $idx, int $value) { - nqp::bindpos_i(self, $idx, $value) - } - multi method ASSIGN-POS(intarray:D: int $idx, Int:D $value) { - nqp::bindpos_i(self, $idx, $value) - } - multi method ASSIGN-POS(intarray:D: Int:D $idx, Int:D $value) { - nqp::bindpos_i(self, $idx, $value) - } - multi method ASSIGN-POS(intarray:D: Any $idx, Mu \value) { + multi method ASSIGN-POS(intarray:D: Any $idx, Mu \value --> Nil) { X::TypeCheck.new( operation => "assignment to int array element #$idx", got => value, @@ -618,6 +647,7 @@ :action, :what(self.^name) ).throw, nqp::stmts( + nqp::setelems(self,0), $iterator.push-all(self), self ) @@ -657,7 +687,7 @@ nqp::push_i(self, $value); self } - multi method push(intarray:D: Mu \value) { + multi method push(intarray:D: Mu \value --> Nil) { X::TypeCheck.new( operation => 'push to int array', got => value, @@ -1107,29 +1137,41 @@ my role numarray[::T] does Positional[T] is array_type(T) { #- start of generated part of numarray role ----------------------------------- -#- Generated on 2018-09-15T11:00:21+02:00 by tools/build/makeNATIVE_ARRAY.p6 +#- Generated on 2018-12-12T18:28:48+01:00 by tools/build/makeNATIVE_ARRAY.p6 #- PLEASE DON'T CHANGE ANYTHING BELOW THIS LINE - multi method AT-POS(numarray:D: int $idx) is raw { - nqp::atposref_n(self, $idx) - } - multi method AT-POS(numarray:D: Int:D $idx) is raw { - nqp::atposref_n(self, $idx) - } - - multi method ASSIGN-POS(numarray:D: int $idx, num $value) { - nqp::bindpos_n(self, $idx, $value) + multi method AT-POS(numarray:D: int $idx --> num) is raw { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::atposref_n(self,$idx) + } + multi method AT-POS(numarray:D: Int:D $idx --> num) is raw { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::atposref_n(self,$idx) + } + + multi method ASSIGN-POS(numarray:D: int $idx, num $value --> num) { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_n(self, $idx, $value) + } + multi method ASSIGN-POS(numarray:D: Int:D $idx, num $value --> num) { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_n(self, $idx, $value) + } + multi method ASSIGN-POS(numarray:D: int $idx, Num:D $value --> num) { + nqp::islt_i($idx,0) + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_n(self, $idx, $value) + } + multi method ASSIGN-POS(numarray:D: Int:D $idx, Num:D $value --> num) { + $idx < 0 + ?? INDEX_OUT_OF_RANGE($idx) + !! nqp::bindpos_n(self, $idx, $value) } - multi method ASSIGN-POS(numarray:D: Int:D $idx, num $value) { - nqp::bindpos_n(self, $idx, $value) - } - multi method ASSIGN-POS(numarray:D: int $idx, Num:D $value) { - nqp::bindpos_n(self, $idx, $value) - } - multi method ASSIGN-POS(numarray:D: Int:D $idx, Num:D $value) { - nqp::bindpos_n(self, $idx, $value) - } - multi method ASSIGN-POS(numarray:D: Any $idx, Mu \value) { + multi method ASSIGN-POS(numarray:D: Any $idx, Mu \value --> Nil) { X::TypeCheck.new( operation => "assignment to num array element #$idx", got => value, @@ -1153,6 +1195,7 @@ :action, :what(self.^name) ).throw, nqp::stmts( + nqp::setelems(self,0), $iterator.push-all(self), self ) @@ -1192,7 +1235,7 @@ nqp::push_n(self, $value); self } - multi method push(numarray:D: Mu \value) { + multi method push(numarray:D: Mu \value --> Nil) { X::TypeCheck.new( operation => 'push to num array', got => value, @@ -1979,7 +2022,7 @@ ), nqp::unless( nqp::islt_i($i,$elems) || iter.is-lazy, - nqp::atpos_i(list,$i) # too many values on non-lazy it + nqp::atpos_i(self,$i) # too many values on non-lazy it ), self ) @@ -3228,6 +3271,11 @@ elsif $kind == 3 { $what := arr.^mixin(strarray[$t]); } +#?if js + elsif $kind == 4 || $kind == 5 { + $what := arr.^mixin(intarray[$t]); + } +#?endif else { return "Can only parameterize array with a native type, not {t.^name}"; } @@ -3297,6 +3345,8 @@ multi method elems(array:D:) { nqp::elems(self) } method shape() { (*,) } + proto method Real(|) {*} + multi method Real(array:D:) { nqp::elems(self) } proto method Int(|) {*} multi method Int(array:D:) { nqp::elems(self) } multi method end(array:D:) { nqp::elems(self) - 1 } diff -Nru rakudo-2018.10/src/core/Nil.pm6 rakudo-2018.12/src/core/Nil.pm6 --- rakudo-2018.10/src/core/Nil.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Nil.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1,5 +1,3 @@ -class X::Assignment::RO { ... } - my class Nil is Cool { # declared in BOOTSTRAP method new(*@ --> Nil) { } multi method gist(Nil:) { 'Nil' } diff -Nru rakudo-2018.10/src/core/ObjAt.pm6 rakudo-2018.12/src/core/ObjAt.pm6 --- rakudo-2018.10/src/core/ObjAt.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/ObjAt.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -29,4 +29,11 @@ } } +multi sub infix:(ObjAt:D $a, ObjAt:D $b) { + nqp::hllbool( + nqp::eqaddr($a.WHAT,$b.WHAT) + && nqp::iseq_s(nqp::unbox_s($a),nqp::unbox_s($b)) + ) +} + # vim: ft=perl6 expandtab sw=4 diff -Nru rakudo-2018.10/src/core/Pod.pm6 rakudo-2018.12/src/core/Pod.pm6 --- rakudo-2018.10/src/core/Pod.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Pod.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -8,7 +8,7 @@ my $leading = ' ' x $level; my %confs; my @chunks; - for { + for { my $thing = $pod.?"$_"(); if $thing { %confs{$_} = nqp::istype($thing,Iterable) @@ -46,7 +46,6 @@ my class Pod::Block::Comment is Pod::Block { } my class Pod::Block::Code is Pod::Block { - has @.allowed; } my class Pod::Block::Declarator is Pod::Block { @@ -69,11 +68,14 @@ method contents { if @!leading && @!trailing { [ $.leading ~ "\n" ~ $.trailing ] - } elsif @!leading { + } + elsif @!leading { [ $.leading ] - } elsif @!trailing { + } + elsif @!trailing { [ $.trailing ] - } else { + } + else { [] } } diff -Nru rakudo-2018.10/src/core/Proc/Async.pm6 rakudo-2018.12/src/core/Proc/Async.pm6 --- rakudo-2018.10/src/core/Proc/Async.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Proc/Async.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -97,8 +97,9 @@ has $!stderr_descriptor_vow; has $!stdout_descriptor_used = Promise.new; has $!stderr_descriptor_used = Promise.new; - has $.path; - has @.args; + has $.path; # XXX TODO deprecated on 2018-11-04 + has @.args; # XXX TODO deprecated on 2018-11-04 + has @.command is List; has $.w; has $.enc = 'utf8'; has $.translate-nl = True; @@ -120,8 +121,11 @@ proto method new(|) {*} multi method new(*@args where .so) { + # XXX TODO .args and .path deprecated on 2018-11-04 to be + # replaced by .command https://github.com/rakudo/rakudo/issues/2444 + my @command := @args.List; my $path = @args.shift; - self.bless(:$path, :@args, |%_) + self.bless(:$path, :@args, :@command, |%_) } submethod TWEAK(--> Nil) { diff -Nru rakudo-2018.10/src/core/Promise.pm6 rakudo-2018.12/src/core/Promise.pm6 --- rakudo-2018.10/src/core/Promise.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Promise.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -33,19 +33,20 @@ has $!cond; has $!thens; has Mu $!dynamic_context; + has Bool $!report-broken-if-sunk; - submethod new(:$scheduler = $*SCHEDULER) { + submethod new(:$scheduler = $*SCHEDULER, :$report-broken-if-sunk) { my \p = nqp::create(self); - p.BUILD(:$scheduler); + p.BUILD(:$scheduler, :$report-broken-if-sunk); p } - submethod BUILD(:$scheduler = $*SCHEDULER --> Nil) { - $!scheduler := $scheduler; - $!lock := nqp::create(Lock); - $!cond := $!lock.condition(); - $!status := Planned; - $!thens := nqp::list(); + submethod BUILD(:$!scheduler = $*SCHEDULER, :$report-broken-if-sunk --> Nil) { + $!report-broken-if-sunk := so $report-broken-if-sunk; + $!lock := nqp::create(Lock); + $!cond := $!lock.condition(); + $!status := Planned; + $!thens := nqp::list(); } # A Vow is used to enable the right to keep/break a promise @@ -239,8 +240,15 @@ } } - method start(Promise:U: &code, :&catch, :$scheduler = $*SCHEDULER, |c) { - my $p := self.new(:$scheduler); + method sink(--> Nil) { + if $!report-broken-if-sunk && $!lock.protect({ not nqp::elems($!thens) }) { + self.then({ .status == Broken && $!scheduler.handle_uncaught(.cause) }); + } + } + + method start(Promise:U: &code, :&catch, :$scheduler = $*SCHEDULER, + :$report-broken-if-sunk, |c) { + my $p := self.new(:$scheduler, :$report-broken-if-sunk); nqp::bindattr($p, Promise, '$!dynamic_context', nqp::ctx()); my $vow := $p.vow; $scheduler.cue( diff -Nru rakudo-2018.10/src/core/QuantHash.pm6 rakudo-2018.12/src/core/QuantHash.pm6 --- rakudo-2018.10/src/core/QuantHash.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/QuantHash.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1,5 +1,7 @@ my role QuantHash does Associative { + method keyof() { Any } + method SET-SELF(QuantHash:D: \elems) { # cannot be a private method nqp::stmts( nqp::if( diff -Nru rakudo-2018.10/src/core/RaceSeq.pm6 rakudo-2018.12/src/core/RaceSeq.pm6 --- rakudo-2018.10/src/core/RaceSeq.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/RaceSeq.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -37,7 +37,7 @@ method race(RaceSeq:D:) { self } - method is-lazy() { False } + method is-lazy(--> False) { } multi method serial(RaceSeq:D:) { self.Seq } diff -Nru rakudo-2018.10/src/core/Rakudo/Internals.pm6 rakudo-2018.12/src/core/Rakudo/Internals.pm6 --- rakudo-2018.10/src/core/Rakudo/Internals.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Rakudo/Internals.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -15,6 +15,8 @@ my class X::Str::Sprintf::Directives::Unsupported { ... } my class X::TypeCheck { ... } +my $CORE_METAOP_ASSIGN := nqp::null; # lazy storage for core METAOP_ASSIGN ops + my class Rakudo::Internals { # for use in nqp::splice @@ -424,12 +426,15 @@ nqp::istype((my $dim := nqp::atpos($spec,$i)),Whatever), X::NYI.new(feature => 'Jagged array shapes').throw, nqp::if( - nqp::isbig_I(nqp::decont($dim := nqp::decont($dim.Int))) - || nqp::isle_i($dim,0), - X::IllegalDimensionInShape.new(:$dim).throw, - nqp::stmts( - nqp::push($types,type), - nqp::push_i($dims,$dim) + nqp::istype(($dim := nqp::decont($dim.Int)),Failure), + $dim.throw, + nqp::if( + nqp::isbig_I($dim) || nqp::isle_i($dim,0), + X::IllegalDimensionInShape.new(:$dim).throw, + nqp::stmts( + nqp::push($types,type), + nqp::push_i($dims,$dim) + ) ) ) ) @@ -761,7 +766,7 @@ } # easy access to compile options - my Mu $compiling-options := nqp::atkey(%*COMPILING, '%?OPTIONS'); + my Mu $compiling-options := %*COMPILING ?? nqp::atkey(%*COMPILING, '%?OPTIONS') !! nqp::hash(); # running with --ll-exception method LL-EXCEPTION() { @@ -1615,6 +1620,25 @@ ) } + # Method for lazily installing fast versions of METAOP_ASSIGN ops for + # core infix ops. Since the compilation of &[op] happens at build time + # of the setting, we're sure we're referring to the core ops and not one + # that has been locally installed. Called by METAOP_ASSIGN. Please add + # any other core ops that seem to be necessary. + method INSTALL-CORE-METAOPS() { + $CORE_METAOP_ASSIGN := nqp::create(Rakudo::Internals::IterationSet); + for ( + &[+], -> Mu \a, Mu \b { a = a.DEFINITE ?? a + b !! +b }, + &[%], -> Mu \a, Mu \b { a = a.DEFINITE ?? a % b !! Failure.new("No zero-arg meaning for infix:<%>")}, + &[-], -> Mu \a, Mu \b { a = a.DEFINITE ?? a - b !! -b }, + &[*], -> Mu \a, Mu \b { a = a.DEFINITE ?? a * b !! +b }, + &[~], -> Mu \a, Mu \b { a = a.DEFINITE ?? a ~ b !! ~b }, + ) -> \op, \metaop { + metaop.set_name(op.name ~ ' + {assigning}'); + nqp::bindkey($CORE_METAOP_ASSIGN,nqp::objectid(op),metaop); + } + $CORE_METAOP_ASSIGN + } } # expose the number of bits a native int has diff -Nru rakudo-2018.10/src/core/Rakudo/Iterator.pm6 rakudo-2018.12/src/core/Rakudo/Iterator.pm6 --- rakudo-2018.10/src/core/Rakudo/Iterator.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Rakudo/Iterator.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -503,6 +503,34 @@ } method AntiPair(\iterator) { AntiPair.new(iterator) } + # Return an iterator that takes an Associative and an Iterable that + # generates keys, to call the AT-KEY method on the Associative. + my class AssociativeIterableKeys does Iterator { + has $!associative; + has $!iterator; + method !SET-SELF($!associative,$!iterator) { self } + method new(\asso,\iter) { nqp::create(self)!SET-SELF(asso,iter) } + + method pull-one() is raw { + nqp::if( + nqp::eqaddr((my \key := $!iterator.pull-one),IterationEnd), + IterationEnd, + $!associative.AT-KEY(key) + ) + } + method push-all($target --> IterationEnd) { + my \iterator := $!iterator; + my \associative := $!associative; + nqp::until( + nqp::eqaddr((my \key := iterator.pull-one),IterationEnd), + $target.push(associative.AT-KEY(key)) + ) + } + } + method AssociativeIterableKeys(\asso, \iterable) { + AssociativeIterableKeys.new(asso,iterable.iterator) + } + # Return an iterator that batches the given source iterator in # batches of the given size. The third parameter indicates whether # a partial batch should be returned when the source iterator has @@ -904,12 +932,7 @@ method new(\iterables) { nqp::create(self)!SET-SELF(iterables) } method pull-one() { nqp::if( -#?if jvm - nqp::eqaddr($!next,Mu), -#?endif -#?if !jvm - nqp::isnull($!next), -#?endif + nqp::eqaddr($!next,IterationEnd), IterationEnd, nqp::stmts( @@ -1044,16 +1067,9 @@ ), nqp::if( nqp::iseq_i($level,-1), - # was last iteration, free up everything now - ($!next := - $!iterators := $!reifieds := $!indices := -#?if jvm - Mu) -#?endif -#?if !jvm - nqp::null) -#?endif + ($!next := $!iterators := $!reifieds := $!indices := + IterationEnd) ) ) ), @@ -1177,12 +1193,7 @@ method new(\its,\map) { nqp::create(self)!SET-SELF(its,map) } method pull-one() { nqp::if( -#?if jvm - nqp::eqaddr($!next,Mu), -#?endif -#?if !jvm - nqp::isnull($!next), -#?endif + nqp::eqaddr($!next,IterationEnd), IterationEnd, nqp::stmts( @@ -1319,16 +1330,9 @@ ), nqp::if( nqp::iseq_i($level,-1), - # was last iteration, free up everything now - ($!next := - $!iterators := $!reifieds := $!indices := -#?if jvm - Mu) -#?endif -#?if !jvm - nqp::null) -#?endif + ($!next := $!iterators := $!reifieds := $!indices := + IterationEnd) ) ) ), @@ -1513,7 +1517,7 @@ self.pull-one, ), nqp::stmts( # save / return value - $!buffer.push(value), + nqp::push($!buffer,value), value ) ) @@ -2391,56 +2395,32 @@ } method pull-one() is raw { nqp::if( -#?if jvm nqp::eqaddr($!value,IterationEnd), -#?endif -#?if !jvm - nqp::isnull($!value), -#?endif IterationEnd, nqp::stmts( (my Mu $value := $!value), -#?if jvm ($!value := IterationEnd), -#?endif -#?if !jvm - ($!value := nqp::null), -#?endif $value ) ) } method push-all($target --> IterationEnd) { nqp::stmts( -#?if jvm - nqp::unless(nqp::eqaddr($!value,IterationEnd),$target.push($!value)), + nqp::unless( + nqp::eqaddr($!value,IterationEnd), + $target.push($!value) + ), ($!value := IterationEnd) -#?endif -#?if !jvm - nqp::unless(nqp::isnull($!value),$target.push($!value)), - ($!value := nqp::null) -#?endif ) } method skip-one() { nqp::if( -#?if jvm nqp::not_i(nqp::eqaddr($!value,IterationEnd)), nqp::isfalse($!value := IterationEnd) -#?endif -#?if !jvm - nqp::not_i(nqp::isnull($!value)), - nqp::isfalse($!value := nqp::null) -#?endif ) } method sink-all(--> IterationEnd) { -#?if jvm $!value := IterationEnd -#?endif -#?if !jvm - $!value := nqp::null -#?endif } } method OneValue(Mu \value) { OneValue.new(value) } @@ -2884,12 +2864,7 @@ method new(\iter) { nqp::create(self)!SET-SELF(iter) } method pull-one() is raw { nqp::if( -#?if jvm - nqp::eqaddr($!iterator,Mu), -#?endif -#?if !jvm - nqp::isnull($!iterator), -#?endif + nqp::eqaddr($!iterator,IterationEnd), nqp::atpos( # supplying from cache $!reified, nqp::mod_i( @@ -2905,12 +2880,7 @@ nqp::if( nqp::elems($!reified), nqp::stmts( # exhausted, something in cache -#?if jvm - ($!iterator := Mu), -#?endif -#?if !jvm - ($!iterator := nqp::null), -#?endif + ($!iterator := IterationEnd), nqp::atpos($!reified,0) ), IterationEnd # exhausted, nothing in cache @@ -3190,12 +3160,7 @@ method new(\iterables) { nqp::create(self)!SET-SELF(iterables) } method pull-one() { nqp::if( -#?if jvm - nqp::eqaddr($!iters,Mu), -#?endif -#?if !jvm - nqp::isnull($!iters), -#?endif + nqp::eqaddr($!iters,IterationEnd), IterationEnd, nqp::stmts( (my int $i = -1), @@ -3219,15 +3184,7 @@ nqp::if( nqp::elems($buf), $buf.List, - nqp::stmts( # we're done -#?if jvm - ($!iters := Mu), -#?endif -#?if !jvm - ($!iters := nqp::null), -#?endif - IterationEnd - ) + ($!iters := IterationEnd), # we're done ) ) ) @@ -3572,7 +3529,6 @@ } method pull-one() is raw { nqp::if( -#?if jvm nqp::eqaddr($!val1,IterationEnd), nqp::if( nqp::eqaddr($!val2,IterationEnd), @@ -3586,29 +3542,12 @@ nqp::stmts( (my $val1 := $!val1), ($!val1 := IterationEnd), -#?endif -#?if !jvm - nqp::isnull($!val1), - nqp::if( - nqp::isnull($!val2), - IterationEnd, - nqp::stmts( - (my Mu $val2 := $!val2), - ($!val2 := nqp::null), - $val2 - ) - ), - nqp::stmts( - (my $val1 := $!val1), - ($!val1 := nqp::null), -#?endif $val1 ) ) } method push-all($target --> IterationEnd) { nqp::stmts( -#?if jvm nqp::if( nqp::eqaddr($!val1,IterationEnd), nqp::unless(nqp::eqaddr($!val2,Mu),$target.push($!val2)), @@ -3618,46 +3557,20 @@ ) ), ($!val1 := $!val2 := IterationEnd) -#?endif -#?if !jvm - nqp::if( - nqp::isnull($!val1), - nqp::unless(nqp::isnull($!val2),$target.push($!val2)), - nqp::stmts( - $target.push($!val1), - $target.push($!val2) - ) - ), - ($!val1 := $!val2 := nqp::null) -#?endif ) } method skip-one() { nqp::if( -#?if jvm nqp::not_i(nqp::eqaddr($!val1,IterationEnd)), nqp::isfalse($!val1 := IterationEnd), nqp::if( nqp::not_i(nqp::eqaddr($!val2,IterationEnd)), nqp::isfalse($!val2 := IterationEnd) -#?endif -#?if !jvm - nqp::not_i(nqp::isnull($!val1)), - nqp::isfalse($!val1 := nqp::null), - nqp::if( - nqp::not_i(nqp::isnull($!val2)), - nqp::isfalse($!val2 := nqp::null) -#?endif ) ) } method sink-all(--> IterationEnd) { -#?if jvm $!val1 := $!val2 := IterationEnd -#?endif -#?if !jvm - $!val1 := $!val2 := nqp::null -#?endif } } method TwoValues(Mu \val1, Mu \val2) { TwoValues.new(val1, val2) } @@ -4014,12 +3927,7 @@ method new(\iterables) { nqp::create(self)!SET-SELF(iterables) } method pull-one() { nqp::if( -#?if jvm - nqp::eqaddr($!iters,Mu), -#?endif -#?if !jvm - nqp::isnull($!iters), -#?endif + nqp::eqaddr($!iters,IterationEnd), IterationEnd, nqp::stmts( (my int $i = -1), @@ -4039,12 +3947,7 @@ nqp::if( $is_iterend, # at least one exhausted nqp::stmts( -#?if jvm - ($!iters := Mu), -#?endif -#?if !jvm - ($!iters := nqp::null), -#?endif + ($!iters := IterationEnd), IterationEnd ), buf.List @@ -4102,12 +4005,7 @@ method new(\iters,\map) { nqp::create(self)!SET-SELF(iters,map) } method pull-one() { nqp::if( -#?if jvm - nqp::eqaddr($!iters,Mu), -#?endif -#?if !jvm - nqp::isnull($!iters), -#?endif + nqp::eqaddr($!iters,IterationEnd), IterationEnd, nqp::stmts( (my int $i = -1), @@ -4119,7 +4017,8 @@ nqp::islt_i(($i = nqp::add_i($i,1)),$elems), nqp::if( nqp::eqaddr( - (my \pulled := nqp::atpos($!iters,$i).pull-one), IterationEnd + (my \pulled := nqp::atpos($!iters,$i).pull-one), + IterationEnd ), $is_iterend = 1, nqp::bindpos($list,$i,pulled) @@ -4127,15 +4026,7 @@ ), nqp::if( $is_iterend, # at least one exhausted - nqp::stmts( -#?if jvm - ($!iters := Mu), -#?endif -#?if !jvm - ($!iters := nqp::null), -#?endif - IterationEnd - ), + ($!iters := IterationEnd), $!mapper($list) ) ) diff -Nru rakudo-2018.10/src/core/Rakudo/QuantHash.pm6 rakudo-2018.12/src/core/Rakudo/QuantHash.pm6 --- rakudo-2018.10/src/core/Rakudo/QuantHash.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Rakudo/QuantHash.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -334,6 +334,20 @@ ) } + # Add to given IterationSet with setty semantics the values of the two + # given iterators where the first iterator supplies objects, and the + # second supplies values (only include if value is trueish). + method ADD-OBJECTS-VALUES-TO-SET(\elems,Mu \objects, Mu \bools) is raw { + nqp::until( + nqp::eqaddr((my \object := objects.pull-one),IterationEnd), + nqp::if( + bools.pull-one, + nqp::bindkey(elems,object.WHICH,nqp::decont(object)) + ) + ); + elems + } + # Add to given IterationSet with setty semantics the keys of given Map method ADD-MAP-TO-SET(\elems, \map) { nqp::stmts( @@ -818,6 +832,20 @@ ) } + # Add to given IterationSet with baggy semantics the values of the two + # given iterators where the first iterator supplies objects, and the + # second supplies values. + method ADD-OBJECTS-VALUES-TO-BAG(\elems,Mu \objects, Mu \values) is raw { + nqp::until( + nqp::eqaddr((my \object := objects.pull-one),IterationEnd), + nqp::if( + (my \value := values.pull-one.Int) > 0, + nqp::bindkey(elems,object.WHICH,Pair.new(object,value)) + ) + ); + elems + } + # Take the given IterationSet with baggy semantics, and add the other # IterationSet with setty semantics to it. Return the given IterationSet. method ADD-SET-TO-BAG(\elems,Mu \set) { @@ -1242,6 +1270,33 @@ ) } + # Add to given IterationSet with mixy semantics the values of the two + # given iterators where the first iterator supplies objects, and the + # second supplies values. + method ADD-OBJECTS-VALUES-TO-MIX(\elems,Mu \objects, Mu \values) is raw { + nqp::until( + nqp::eqaddr((my \object := objects.pull-one),IterationEnd), + nqp::if( + nqp::istype((my \value := values.pull-one),Num) + && nqp::isnanorinf(value), + X::OutOfRange.new( # NaN or -Inf or Inf, we're done + what => 'Value', + got => value, + range => '-Inf^..^Inf' + ).throw, + nqp::if( + nqp::istype(nqp::bind(value,value.Real),Real), + nqp::if( + value, + nqp::bindkey(elems,object.WHICH,Pair.new(object,value)) + ), + value.throw + ) + ) + ); + elems + } + # Take the given IterationSet with mixy semantics, and add the other # IterationSet with setty semantics to it. Return the given IterationSet. method ADD-SET-TO-MIX(\elems,Mu \set) { diff -Nru rakudo-2018.10/src/core/Range.pm6 rakudo-2018.12/src/core/Range.pm6 --- rakudo-2018.10/src/core/Range.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Range.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -149,12 +149,12 @@ !! Rakudo::Iterator.SuccFromInf( $!excludes-min ?? $!min.succ !! $!min ) - !! nqp::istype($!min,Str) && nqp::istype($!max,Str) + !! nqp::istype($!min,Str) # we have a string range ?? $!min.chars == 1 && $!max.chars == 1 # we have (simple) char range ?? Rakudo::Iterator.CharFromTo( - $!min,$!max,$!excludes-min,$!excludes-max + $!min,$!max.Str,$!excludes-min,$!excludes-max ) # generic string sequence !! SEQUENCE( diff -Nru rakudo-2018.10/src/core/Regex.pm6 rakudo-2018.12/src/core/Regex.pm6 --- rakudo-2018.10/src/core/Regex.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Regex.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -5,9 +5,6 @@ # has %!alt_nfas; # has str $!source; - # cache cursor initialization lookup - my $cursor-init := Match.^lookup("!cursor_init"); - proto method ACCEPTS(|) {*} multi method ACCEPTS(Regex:D: Mu:U \a) { False @@ -19,11 +16,18 @@ nqp::hllbool(nqp::istype(topic, self)) } + # Create a braid and fail cursor that we can use with all the normal, + # "boring", regex matches that are on the Regex type. This saves them + # being created every single time. + my $cursor := Match.'!cursor_init'(''); + my $braid := $cursor.braid; + my $fail_cursor := $cursor.'!cursor_start_cur'(); + multi method ACCEPTS(Regex:D \SELF: Any \topic) { nqp::decont( nqp::getlexrelcaller(nqp::ctxcallerskipthunks(nqp::ctx()),'$/') = nqp::stmts( - (my \cursor := SELF.($cursor-init(Match, topic, :c(0)))), + (my \cursor := SELF.(Match.'!cursor_init'(topic, :c(0), :$braid, :$fail_cursor))), nqp::if( nqp::isge_i(nqp::getattr_i(cursor,Match,'$!pos'),0), cursor.MATCH, @@ -62,7 +66,7 @@ (my $pulled := iter.pull-one),IterationEnd) || nqp::isge_i( # valid match? nqp::getattr_i( - (my \cursor := SELF.($cursor-init(Match,$pulled,:0c))), + (my \cursor := SELF.(Match.'!cursor_init'($pulled,:0c,:$braid,:$fail_cursor))), Match,'$!pos'), 0), nqp::null diff -Nru rakudo-2018.10/src/core/set_addition.pm6 rakudo-2018.12/src/core/set_addition.pm6 --- rakudo-2018.10/src/core/set_addition.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/set_addition.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -144,7 +144,7 @@ multi sub infix:<(+)>(Failure:D $a, Any $) { $a.throw } multi sub infix:<(+)>(Any $a, Any $b) { nqp::if( - nqp::istype($a,QuantHash), + nqp::istype($a,QuantHash) && nqp::isconcrete($a), nqp::if( nqp::istype($a,Mixy) || nqp::istype($b,Mixy), infix:<(+)>($a.Mixy, $b.Mix(:view)), diff -Nru rakudo-2018.10/src/core/SetHash.pm6 rakudo-2018.12/src/core/SetHash.pm6 --- rakudo-2018.10/src/core/SetHash.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/SetHash.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -194,6 +194,21 @@ ) ) } + multi method STORE(SetHash:D: \objects, \bools --> SetHash:D) { + my \iterobjs := objects.iterator; + my \iterbools := bools.iterator; + nqp::bindattr( + self,SetHash,'$!elems',nqp::create(Rakudo::Internals::IterationSet) + ); + nqp::until( + nqp::eqaddr((my \object := iterobjs.pull-one),IterationEnd), + nqp::if( + iterbools.pull-one, + nqp::bindkey($!elems,object.WHICH,nqp::decont(object)) + ) + ); + self + } multi method AT-KEY(SetHash:D: \k --> Bool:D) is raw { Proxy.new( diff -Nru rakudo-2018.10/src/core/set_intersection.pm6 rakudo-2018.12/src/core/set_intersection.pm6 --- rakudo-2018.10/src/core/set_intersection.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/set_intersection.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -130,7 +130,35 @@ # Note that we cannot create a Setty:D,Any candidate because that will result # in an ambiguous dispatch, so we need to hack a check for Setty in here. multi sub infix:<(&)>(Any $a, Any $b) { - infix:<(&)>(nqp::istype($a,Setty) ?? $a !! $a.Set,$b.Set) + nqp::if( + nqp::isconcrete($a), + nqp::if( + nqp::istype($a,Mixy), + infix:<(&)>($a, $b.Mix), + nqp::if( + nqp::istype($a,Baggy), + infix:<(&)>($a, $b.Bag), + nqp::if( + nqp::istype($a,Setty), + infix:<(&)>($a, $b.Set), + nqp::if( + nqp::isconcrete($b), + nqp::if( + nqp::istype($b,Mixy), + infix:<(&)>($a.Mix, $b), + nqp::if( + nqp::istype($b,Baggy), + infix:<(&)>($a.Bag, $b), + infix:<(&)>($a.Set, $b.Set) + ) + ), + infix:<(&)>($a, $b.Set) + ) + ) + ) + ), + infix:<(&)>($a.Set, $b) + ) } multi sub infix:<(&)>(**@p) { diff -Nru rakudo-2018.10/src/core/set_multiply.pm6 rakudo-2018.12/src/core/set_multiply.pm6 --- rakudo-2018.10/src/core/set_multiply.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/set_multiply.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -54,9 +54,11 @@ # in here. multi sub infix:<(.)>(Any $a, Any $b) { infix:<(.)>( - nqp::istype($a,Setty) - ?? $a.Baggy - !! nqp::istype($a,Baggy) ?? $a !! $a.Bag, + nqp::isconcrete($a) + ?? nqp::istype($a,Setty) + ?? $a.Baggy + !! nqp::istype($a,Baggy) ?? $a !! $a.Bag + !! $a.Bag, $b.Bag ) } diff -Nru rakudo-2018.10/src/core/Set.pm6 rakudo-2018.12/src/core/Set.pm6 --- rakudo-2018.10/src/core/Set.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Set.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -93,6 +93,15 @@ !! self.SET-SELF(Rakudo::QuantHash.ADD-PAIRS-TO-SET( nqp::create(Rakudo::Internals::IterationSet), $iterator)) } + multi method STORE(Set:D: \objects, \bools, :$INITIALIZE! --> Set:D) { + self.SET-SELF( + Rakudo::QuantHash.ADD-OBJECTS-VALUES-TO-SET( + nqp::create(Rakudo::Internals::IterationSet), + objects.iterator, + bools.iterator + ) + ) + } multi method AT-KEY(Set:D: \k --> Bool:D) { nqp::hllbool($!elems ?? nqp::existskey($!elems,k.WHICH) !! 0) diff -Nru rakudo-2018.10/src/core/set_precedes.pm6 rakudo-2018.12/src/core/set_precedes.pm6 --- rakudo-2018.10/src/core/set_precedes.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/set_precedes.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -5,13 +5,14 @@ # ≽ succeeds proto sub infix:<<(<+)>>($, $, *% --> Bool:D) is pure { + die if $*FOLDING; # not going to constant fold something that's deprecated Rakudo::Deprecations.DEPRECATED( "set operator {$*INSTEAD // "(<=)"}", "", "6.d", :what("Set operator {$*WHAT // "(<+)"}"), :up( 1 + ?$*WHAT ) - ); + ) unless $*INTERNAL; {*} } multi sub infix:<<(<+)>>(Setty:D \a, QuantHash:D \b --> Bool:D) { @@ -102,6 +103,7 @@ multi sub infix:<<(<+)>>(Any $, Failure:D $b) { $b.throw } multi sub infix:<<(<+)>>(Failure:D $a, Any $) { $a.throw } multi sub infix:<<(<+)>>(Any $a, Any $b --> Bool:D) { + my $*INTERNAL = 1; nqp::if( nqp::istype($a,Mixy) || nqp::istype($b,Mixy), infix:<<(<+)>>($a.Mix, $b.Mix), diff -Nru rakudo-2018.10/src/core/Setty.pm6 rakudo-2018.12/src/core/Setty.pm6 --- rakudo-2018.10/src/core/Setty.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Setty.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1,6 +1,8 @@ my role Setty does QuantHash { has Rakudo::Internals::IterationSet $!elems; # key.WHICH => key + method of() { Bool } + # helper sub to create Set from iterator, check for laziness sub create-from-iterator(\type, \iterator --> Setty:D) { nqp::if( diff -Nru rakudo-2018.10/src/core/set_union.pm6 rakudo-2018.12/src/core/set_union.pm6 --- rakudo-2018.10/src/core/set_union.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/set_union.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -154,25 +154,33 @@ multi sub infix:<(|)>(Any $a, Failure:D $b) { $b.throw } multi sub infix:<(|)>(Any $a, Any $b) { nqp::if( - nqp::istype($a,Mixy), - infix:<(|)>($a, $b.Mix), + nqp::isconcrete($a), nqp::if( - nqp::istype($a,Baggy), - infix:<(|)>($a, $b.Bag), + nqp::istype($a,Mixy), + infix:<(|)>($a, $b.Mix), nqp::if( - nqp::istype($a,Setty), - infix:<(|)>($a, $b.Set), + nqp::istype($a,Baggy), + infix:<(|)>($a, $b.Bag), nqp::if( - nqp::istype($b,Mixy), - infix:<(|)>($a.Mix, $b), + nqp::istype($a,Setty), + infix:<(|)>($a, $b.Set), nqp::if( - nqp::istype($b,Baggy), - infix:<(|)>($a.Bag, $b), - infix:<(|)>($a.Set, $b.Set) + nqp::isconcrete($b), + nqp::if( + nqp::istype($b,Mixy), + infix:<(|)>($a.Mix, $b), + nqp::if( + nqp::istype($b,Baggy), + infix:<(|)>($a.Bag, $b), + infix:<(|)>($a.Set, $b.Set) + ) + ), + infix:<(|)>($a, $b.Set) ) ) ) - ) + ), + infix:<(|)>($a.Set, $b) ) } diff -Nru rakudo-2018.10/src/core/Shaped1Array.pm6 rakudo-2018.12/src/core/Shaped1Array.pm6 --- rakudo-2018.10/src/core/Shaped1Array.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Shaped1Array.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -92,6 +92,17 @@ nqp::bindpos(nqp::getattr(self,List,'$!reified'),one,value) } + method !RE-INITIALIZE(::?CLASS:D:) { + my \list := nqp::getattr(self,List,'$!reified'); + nqp::bind( # rebind newly created list + list, + nqp::bindattr( + self,List,'$!reified', + nqp::setelems(nqp::create(list),nqp::elems(list)) + ) + ) + } + proto method STORE(::?CLASS:D: |) {*} multi method STORE(::?CLASS:D: ::?CLASS:D \from-array) { nqp::stmts( @@ -120,34 +131,32 @@ ) ) } - multi method STORE(::?CLASS:D: Iterable:D \in) { - nqp::stmts( - (my \list := nqp::getattr(self,List,'$!reified')), - (my \desc := nqp::getattr(self,Array,'$!descriptor')), - (my \iter := in.iterator), - (my int $elems = nqp::elems(list)), - (my int $i = -1), - nqp::until( - nqp::eqaddr((my $pulled := iter.pull-one),IterationEnd) - || nqp::iseq_i(($i = nqp::add_i($i,1)),$elems), - nqp::ifnull( - nqp::atpos(list,$i), - nqp::bindpos(list,$i,nqp::p6scalarfromdesc(desc)) - ) = $pulled - ), - nqp::unless( - nqp::islt_i($i,$elems) || iter.is-lazy, - nqp::atpos(list,$i) # too many values on non-lazy iter, error - ), - self - ) + multi method STORE(::?CLASS:D: Iterable:D \in, :$INITIALIZE) { + my \list := $INITIALIZE + ?? nqp::getattr(self,List,'$!reified') + !! self!RE-INITIALIZE; + my \desc := nqp::getattr(self,Array,'$!descriptor'); + my \iter := in.iterator; + my int $i = -1; + my int $elems = nqp::elems(list); + nqp::until( + nqp::eqaddr((my \pulled := iter.pull-one),IterationEnd) + || nqp::iseq_i(($i = nqp::add_i($i,1)),$elems), + nqp::ifnull( + nqp::atpos(list,$i), + nqp::bindpos(list,$i,nqp::p6scalarfromdesc(desc)) + ) = pulled + ); + nqp::atpos(list,$i) # too many values on non-lazy iter, error + unless nqp::islt_i($i,$elems) || iter.is-lazy; + self } - multi method STORE(::?CLASS:D: Mu \item) { - my \reified := nqp::getattr(self,List,'$!reified'); - nqp::ifnull( - nqp::atpos(reified,0), - nqp::bindpos(reified,0, - nqp::p6scalarfromdesc(nqp::getattr(self,Array,'$!descriptor'))) + multi method STORE(::?CLASS:D: Mu \item, :$INITIALIZE) { + my \list := $INITIALIZE + ?? nqp::getattr(self,List,'$!reified') + !! self!RE-INITIALIZE; + nqp::bindpos(list,0, + nqp::p6scalarfromdesc(nqp::getattr(self,Array,'$!descriptor')) ) = item; self } diff -Nru rakudo-2018.10/src/core/ShapedArray.pm6 rakudo-2018.12/src/core/ShapedArray.pm6 --- rakudo-2018.10/src/core/ShapedArray.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/ShapedArray.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -278,11 +278,19 @@ } sub NUMCPY(Mu \to, Mu \from) { NumCopy.new(to,from).sink-all } + method !RE-INITIALIZE(::?CLASS:D:) { + nqp::bindattr( # this is a yucky way to re-init, but it works + self,List,'$!reified', + nqp::getattr(self.new(:shape(self.shape)),List,'$!reified') + ) + } + proto method STORE(::?CLASS:D: |) {*} - multi method STORE(::?CLASS:D: ::?CLASS:D \in) { + multi method STORE(::?CLASS:D: ::?CLASS:D \in, :$INITIALIZE) { nqp::if( in.shape eqv self.shape, nqp::stmts( + nqp::unless($INITIALIZE,self!RE-INITIALIZE), MEMCPY(self,in), # VM-supported memcpy-like thing? self ), @@ -292,10 +300,11 @@ ).throw ) } - multi method STORE(::?CLASS:D: array:D \in) { + multi method STORE(::?CLASS:D: array:D \in, :$INITIALIZE) { nqp::if( in.shape eqv self.shape, nqp::stmts( + nqp::unless($INITIALIZE,self!RE-INITIALIZE), nqp::if( nqp::istype(in.of,Int), INTCPY(self,in), # copy from native int @@ -376,7 +385,8 @@ ) } } - multi method STORE(::?CLASS:D: Iterable:D \in) { + multi method STORE(::?CLASS:D: Iterable:D \in, :$INITIALIZE) { + self!RE-INITIALIZE unless $INITIALIZE; StoreIterable.new(self,in).sink-all; self } @@ -404,7 +414,8 @@ ) } } - multi method STORE(::?CLASS:D: Iterator:D \iterator) { + multi method STORE(::?CLASS:D: Iterator:D \iterator, :$INITIALIZE) { + self!RE-INITIALIZE unless $INITIALIZE; StoreIterator.new(self,iterator).sink-all; self } diff -Nru rakudo-2018.10/src/core/Supply.pm6 rakudo-2018.12/src/core/Supply.pm6 --- rakudo-2018.10/src/core/Supply.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/Supply.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -1537,22 +1537,34 @@ method tap(&emit, &done, &quit, &tap) { my $tle := TapListEntry.new(:&emit, :&done, :&quit); + # Since we run `tap` before adding, there's a small chance of + # a tap removal attempt happening for the add attempt. We use + # these two flags to handle that case. This is safe since we + # only ever access them under lock. + my $added := False; + my $removed := False; my $t = Tap.new({ $!lock.protect({ - my Mu $update := nqp::list(); - for nqp::hllize($!tappers) -> \entry { - nqp::push($update, entry) unless entry =:= $tle; + if $added { + my Mu $update := nqp::list(); + for nqp::hllize($!tappers) -> \entry { + nqp::push($update, entry) unless entry =:= $tle; + } + $!tappers := $update; } - $!tappers := $update; + $removed := True; }); }); tap($t); $!lock.protect({ - my Mu $update := nqp::isconcrete($!tappers) - ?? nqp::clone($!tappers) - !! nqp::list(); - nqp::push($update, $tle); - $!tappers := $update; + unless $removed { + my Mu $update := nqp::isconcrete($!tappers) + ?? nqp::clone($!tappers) + !! nqp::list(); + nqp::push($update, $tle); + $!tappers := $update; + } + $added := True; }); $t } @@ -1660,25 +1672,37 @@ method tap(&emit, &done, &quit, &tap) { my $tle := TapListEntry.new(:&emit, :&done, :&quit); my int $replay = 0; + # Since we run `tap` before adding, there's a small chance of + # a tap removal attempt happening for the add attempt. We use + # these two flags to handle that case. This is safe since we + # only ever access them under lock. + my $added := False; + my $removed := False; my $t = Tap.new({ $!lock.protect({ - my Mu $update := nqp::list(); - for nqp::hllize($!tappers) -> \entry { - nqp::push($update, entry) unless entry =:= $tle; + if $added { + my Mu $update := nqp::list(); + for nqp::hllize($!tappers) -> \entry { + nqp::push($update, entry) unless entry =:= $tle; + } + $!replay-done = 0 if nqp::elems($update) == 0; + $!tappers := $update; } - $!replay-done = 0 if nqp::elems($update) == 0; - $!tappers := $update; + $removed := True; }); }); tap($t); $!lock.protect({ - my Mu $update := nqp::isconcrete($!tappers) - ?? nqp::clone($!tappers) - !! nqp::list(); - nqp::push($update, $tle); - $replay = 1 if nqp::elems($update) == 1; - self!replay($tle) if $replay; - $!tappers := $update; + unless $removed { + my Mu $update := nqp::isconcrete($!tappers) + ?? nqp::clone($!tappers) + !! nqp::list(); + nqp::push($update, $tle); + $replay = 1 if nqp::elems($update) == 1; + self!replay($tle) if $replay; + $!tappers := $update; + } + $added := True; }); $t } @@ -1896,6 +1920,21 @@ $done-handler() if $done-handler.DEFINITE; } + method run-last(Tap $tap, &code --> Nil) { + self.delete-active-tap($tap); + self.decrement-active(); + $tap.close(); + &code.fire_if_phasers("LAST"); + $!lock.protect: { + if $!active == 0 { + self.teardown(); + my $done-handler := &!done; + $done-handler() if $done-handler.DEFINITE; + } + } + } + + method run-catch(--> Nil) { my \ex = EXCEPTION(nqp::exception()); self.get-and-zero-active(); @@ -1928,14 +1967,14 @@ }, -> \value { self!run-supply-code(&whenever-block, value, $state, - &add-whenever) + &add-whenever, $tap) }, done => { $state.delete-active-tap($tap); my @phasers := &whenever-block.phasers('LAST'); if @phasers { self!run-supply-code({ .() for @phasers }, Nil, $state, - &add-whenever) + &add-whenever, $tap) } $tap.close; self!deactivate-one($state); @@ -1952,7 +1991,7 @@ $state.quit().(ex) if $state.quit; $state.teardown(); } - }, Nil, $state, &add-whenever); + }, Nil, $state, &add-whenever, $tap); if $handled { $tap.close; self!deactivate-one($state); @@ -1977,13 +2016,13 @@ # counts as an active runner). self!run-supply-code: { &!block(); self!deactivate-one-internal($state) }, - Nil, $state, &add-whenever; + Nil, $state, &add-whenever, $t; # Evaluate to the Tap. $t } - method !run-supply-code(&code, \value, SupplyBlockState $state, &add-whenever) { + method !run-supply-code(&code, \value, SupplyBlockState $state, &add-whenever, $tap) { my @run-after; my $queued := $state.run-async-lock.protect-or-queue-on-recursion: { my &*ADD-WHENEVER := &add-whenever; @@ -1991,6 +2030,7 @@ 'EMIT', $state.run-emit(), 'DONE', $state.run-done(), 'CATCH', $state.run-catch(), + 'LAST', $state.run-last($tap, &code), 'NEXT', 0); @run-after = $state.awaiter.take-all; } @@ -2080,6 +2120,11 @@ } } + method run-last(&code, --> Nil) { + &code.fire_if_phasers("LAST"); + self.run-done; + } + method run-catch(--> Nil) { if $!active { my \ex = EXCEPTION(nqp::exception()); @@ -2187,6 +2232,7 @@ 'EMIT', $state.run-emit(), 'DONE', $state.run-done(), 'CATCH', $state.run-catch(), + 'LAST', $state.run-last(&code), 'NEXT', 0); }(); # XXX Workaround for optimizer bug } diff -Nru rakudo-2018.10/src/core/traits.pm6 rakudo-2018.12/src/core/traits.pm6 --- rakudo-2018.10/src/core/traits.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/traits.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -453,7 +453,7 @@ } elsif nqp::istype($expr, HyperWhatever) { $pkg.^add_fallback( - -> $obj, $name { True }, + -> $, $ --> True { }, -> $obj, $name { -> $self, |c { $attr.get_value($self)."$name"(|c) diff -Nru rakudo-2018.10/src/core/VM.pm6 rakudo-2018.12/src/core/VM.pm6 --- rakudo-2018.10/src/core/VM.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core/VM.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -55,6 +55,7 @@ method platform-library-name(IO::Path $library, Version :$version) { my int $is-win = Rakudo::Internals.IS-WIN; my int $is-darwin = self.osname eq 'darwin'; + my int $is-openbsd = self.osname eq 'openbsd'; my $basename = $library.basename; my int $full-path = $library ne $basename; @@ -73,7 +74,7 @@ #?endif $platform-name ~= '.' ~ $version - if $version.defined and nqp::iseq_i(nqp::add_i($is-darwin,$is-win),0); + if $version.defined and nqp::iseq_i(nqp::add_i(nqp::add_i($is-darwin,$is-win),$is-openbsd),0); $full-path ?? $dirname.IO.add($platform-name).absolute diff -Nru rakudo-2018.10/src/core.d/operators.pm6 rakudo-2018.12/src/core.d/operators.pm6 --- rakudo-2018.10/src/core.d/operators.pm6 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/core.d/operators.pm6 2018-12-21 05:16:35.000000000 +0000 @@ -7,3 +7,20 @@ multi sub undefine(Mu \x) is raw { x = Nil } multi sub undefine(Array \x) is raw { x = Empty } multi sub undefine(Hash \x) is raw { x = Empty } + +sub infix:<<(<+)>> (|) { + die "(<+) was removed in v6.d, please use (<=) operator instead + or compile your code with 'use v6.c'" +} +sub infix:<≼>(|) { + die "≼ was removed in v6.d, please use ⊆ operator instead + or compile your code with 'use v6.c'" +} +sub infix:<<(>+)>> (|) { + die "(>+) was removed in v6.d, please use (>=) operator instead + or compile your code with 'use v6.c'" +} +sub infix:<≽>(|) { + die "≽ was removed in v6.d, please use ⊇ operator instead + or compile your code with 'use v6.c'" +} diff -Nru rakudo-2018.10/src/Perl6/Actions.nqp rakudo-2018.12/src/Perl6/Actions.nqp --- rakudo-2018.10/src/Perl6/Actions.nqp 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/Perl6/Actions.nqp 2018-12-21 05:16:35.000000000 +0000 @@ -116,7 +116,7 @@ $ast[0] := WANTED($ast[0], $byby) if nqp::elems(@($ast)); $ast.wanted(1); } - elsif $ast.op eq 'p6decontrv' { + elsif $ast.op eq 'p6decontrv' || $ast.op eq 'p6decontrv_6c' { $ast[1] := WANTED($ast[1], $byby) if nqp::elems(@($ast)); $ast.wanted(1); } @@ -335,7 +335,7 @@ $ast[0] := UNWANTED($ast[0], $byby) if nqp::elems(@($ast)); $ast.sunk(1); } - elsif $ast.op eq 'p6decontrv' { + elsif $ast.op eq 'p6decontrv' || $ast.op eq 'p6decontrv_6c' { $ast[1] := UNWANTED($ast[1], $byby) if nqp::elems(@($ast)); $ast.sunk(1); } @@ -859,7 +859,7 @@ :op('call'), QAST::Op.new( :op('speshresolve'), - QAST::SVal.new( :value('decontrv') ), + QAST::SVal.new( :value($qast[1] eq '6c' ?? 'decontrv_6c' !! 'decontrv') ), QAST::Var.new( :name($result), :scope('local') ) ), QAST::Var.new( :name($result), :scope('local') ), @@ -1073,6 +1073,10 @@ } class Perl6::Actions is HLL::Actions does STDActions { + #================================================================ + # AMBIENT AND POD-COMMON CODE HANDLERS + #================================================================ + our @MAX_PERL_VERSION; # Could add to this based on signatures. @@ -1441,443 +1445,180 @@ } } - method pod_content_toplevel($/) { - my $child := $.ast; - # make sure we don't push the same thing twice - if $child { - my $id := $/.from ~ "," ~ ~$/.to; - if !$*POD_BLOCKS_SEEN{$id} { - $*POD_BLOCKS.push($child); - $*POD_BLOCKS_SEEN{$id} := 1; - } - } - make $child; - } - - method pod_content:sym($/) { - make $.ast; - } - - # TODO The spaces arg from Grammar.nqp seems - # NOT to be handled. That shows up - # in testing for config continuation lines. - method pod_configuration($/) { - make Perl6::Pod::make_config($/); + method unitstart($/) { + # Use SET_BLOCK_OUTER_CTX (inherited from HLL::Actions) + # to set dynamic outer lexical context and namespace details + # for the compilation unit. + self.SET_BLOCK_OUTER_CTX($*UNIT_OUTER); } - method pod_block:sym($/) { - if $.Str ~~ /^defn/ { - make Perl6::Pod::defn($/, $delim-block); + method statementlist($/) { + my $past := QAST::Stmts.new( :node($/) ); + if $ { + my int $i := 0; + my int $e := nqp::elems($) - 1; + while $i <= $e { + my $ast := $[$i].ast; + if $ast { + if $ast.ann('statement_level') && $*statement_level { + $ast.ann('statement_level')(); + } + if $ast.ann('sink_ast') { + $ast := QAST::Want.new($ast, 'v', $ast.ann('sink_ast')); + $ast := UNWANTED($ast, 'statementlist/sink_ast') if $i < $e; + } + elsif $ast.ann('bare_block') { + if $i < $e { + $ast := UNWANTED(autosink($ast.ann('bare_block')), "statementlist/bare_block"); + } + elsif $*ESCAPEBLOCK { + $ast := WANTED($ast.ann('bare_block'),'statementlist/escape'); + } + else { + $ast := autosink($ast.ann('bare_block')); + } + } + else { + if nqp::istype($ast,QAST::Op) && ($ast.op eq 'while' || $ast.op eq 'until' || $ast.op eq 'repeat_while' || $ast.op eq 'repeat_until') { + $ast := UNWANTED($ast,'statementlist/loop'); # statement level loops never want return value + } + elsif $i == $e && $*ESCAPEBLOCK { + $ast := QAST::Stmt.new(autosink(WANTED($ast,'statementlist/else')), :returns($ast.returns)); + } + else { + $ast := QAST::Stmt.new(autosink($ast), :returns($ast.returns)); + } + } + $ast.node($[$i]); + $past.push( $ast ); + } + ++$i; + } } - else { - make Perl6::Pod::any_block($/, $delim-block); + if +$past.list < 1 { + $past.push(QAST::WVal.new( :value($*W.find_symbol(['Nil'])) )); } - } - - method pod_block:sym($/) { - make Perl6::Pod::raw_block($/); - } - - method pod_block:sym($/) { - make Perl6::Pod::table($/, $delim-block); - } - - method pod_block:sym($/) { - # TODO add numbered-alias handling - my $config := $.ast; - my @contents := $.ast; - @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; - make Perl6::Pod::serialize_object('Pod::Block::Code', - :@contents,:$config).compile_time_value - } - - method delimited_code_content($/) { - my @contents := []; - for $/[0] { - if $_ { - nqp::splice(@contents, - Perl6::Pod::pod_strings_from_matches($_), - +@contents, 0); - nqp::push(@contents, $*W.add_constant( - 'Str', 'str', ~$_ - ).compile_time_value); - } else { - @contents.push($*W.add_constant('Str', 'str', "\n").compile_time_value); + else { + my $pl := $past[+@($past) - 1]; + if $pl.sunk { + $past.push(QAST::WVal.new( :value($*W.find_symbol(['Nil'])) )); + } + else { + $pl.final(1); + $past.returns($pl.returns); } } - make @contents; + make $past; } - method pod_block:sym($/) { - if $.Str ~~ /^defn/ { - make Perl6::Pod::defn($/, $para-block); + # Produces a LoL from a semicolon list + method semilist($/) { + if $ { + my $past := QAST::Stmts.new( :node($/) ); + if $ > 1 { + my $l := QAST::Op.new( :name('&infix:<,>'), :op('call') ); + for $ { + my $sast := $_.ast || QAST::WVal.new( :value($*W.find_symbol(['Nil'])) ); + $l.push(wanted($sast, 'semilist')); + } + $past.push($l); + $past.annotate('multislice', 1); + } + else { + $past.push($[0].ast || QAST::WVal.new( :value($*W.find_symbol(['Nil'])) )); + } + make $past; } else { - make Perl6::Pod::any_block($/, $para-block); + make QAST::Op.new( :op('call'), :name('&infix:<,>') ); } } - method pod_block:sym($/) { - make Perl6::Pod::raw_block($/); - } - - method pod_block:sym($/) { - make Perl6::Pod::table($/, $para-block); - } - - method pod_block:sym($/) { - # TODO make config via call to make_config in Pod.nqp - my $config := $.ast; - my @contents := []; - for $ { - nqp::splice(@contents, $_.ast, +@contents, 0); + method sequence($/) { + my $past := QAST::Stmts.new( :node($/) ); + if $ { + for $ { $past.push($_.ast) if $_.ast; } } - @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; - make Perl6::Pod::serialize_object('Pod::Block::Code', - :@contents,:$config).compile_time_value; + unless +@($past) { + $past.push( QAST::Op.new( :op('call'), :name('&infix:<,>') ) ); + } + make $past; } - method pod_block:sym($/) { - if $.Str ~~ /^defn/ { - make Perl6::Pod::defn($/, $abbrev-block); - } - else { - make Perl6::Pod::any_block($/, $abbrev-block); + method statement($/) { + my $past; + if $ { + my $mc := $; + my $ml := $; + $past := $.ast; + if $mc { + if ~$mc eq 'with' { + make thunkity_thunk($/,'.b',QAST::Op.new( :op('call'), :name('&infix:')),[$mc,$]); + return; + } + elsif ~$mc eq 'without' { + make thunkity_thunk($/,'.b',QAST::Op.new( :op('call'), :name('&infix:')),[$mc,$]); + return; + } + my $mc_ast := $mc.ast; + if $past.ann('bare_block') { + my $cond_block := $past.ann('past_block'); + remove_block($*W.cur_lexpad(), $cond_block); + $cond_block.blocktype('immediate'); + $past := $cond_block; + } + $mc_ast.push($past); + $mc_ast.push(QAST::WVal.new( :value($*W.find_symbol(['Empty'])) )); + $past := $mc_ast; + } + if $ml { + $past.okifnil(1); + $past[0].okifnil(1) if +@($past); + my $cond := $ml.ast; + if ~$ml eq 'given' { + unless $past.ann('bare_block') { + $past := make_topic_block_ref($/, $past, migrate_stmt_id => $*STATEMENT_ID); + } + $past := QAST::Op.new( :op('call'), block_closure($past), $cond ); + } + elsif ~$ml eq 'for' { + unless $past.ann('past_block') { + $past := make_topic_block_ref($/, $past, migrate_stmt_id => $*STATEMENT_ID); + } + my $fornode := QAST::Op.new( + :op, :node($/), + $cond, + block_closure($past), + ); + $past := QAST::Want.new( + $fornode, + 'v', QAST::Op.new(:op, $fornode), + ); + $past[2].sunk(1); + my $sinkee := $past[0]; + $past.annotate('statement_level', -> { + UNWANTED($sinkee, 'force for mod'); + $fornode.op('p6forstmt') if can-use-p6forstmt($fornode[1]); + $fornode.annotate('IterationEnd', $*W.find_symbol(['IterationEnd'])); + $fornode.annotate('Nil', $*W.find_symbol(['Nil'])); + }); + } + else { + $past := QAST::Op.new($cond, $past, :op(~$ml), :node($/) ); + } + } } - } + elsif $ { $past := $.ast; } + elsif $ { $past := $.ast; } + else { $past := 0; } - method pod_block:sym($/) { - make Perl6::Pod::raw_block($/); - } + if $past { + my $id := $*STATEMENT_ID; + $past.annotate('statement_id', $id); - method pod_block:sym($/) { - make Perl6::Pod::table($/, $abbrev-block); - } - - method pod_block:sym($/) { - my @contents := []; - for $ { - nqp::splice(@contents, $_.ast, +@contents, 0); - } - @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; - make Perl6::Pod::serialize_object( - 'Pod::Block::Code', :@contents - ).compile_time_value - } - - method pod_line ($/) { - my @contents := Perl6::Pod::pod_strings_from_matches($); - @contents.push($*W.add_constant( - 'Str', 'str', ~$ - ).compile_time_value); - make @contents; - } - - method pod_block:sym($/) { - $*W.install_lexical_symbol( - $*UNIT,'$=finish', nqp::hllizefor(~$, 'perl6')); - } - - method pod_content:sym($/) { - make Perl6::Pod::config($/); - } - - method pod_content:sym($/) { - my @ret := []; - for $ { - @ret.push($_.ast); - } - my $past := Perl6::Pod::serialize_array(@ret); - make $past.compile_time_value; - } - - method pod_textcontent:sym($/) { - my @contents := Perl6::Pod::pod_strings_from_matches($); - @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; - make Perl6::Pod::serialize_object('Pod::Block::Para', :@contents).compile_time_value - } - - method pod_textcontent:sym($/) { - my $s := $.Str; - my $t := subst($.Str, /\n$s/, "\n", :global); - $t := subst($t, /\n$/, ''); # chomp! - my $past := Perl6::Pod::serialize_object( - 'Pod::Block::Code', - :contents(Perl6::Pod::serialize_aos([$t]).compile_time_value), - ); - make $past.compile_time_value; - } - - method pod_formatting_code($/) { - if $ eq 'V' { - make ~$; - } elsif $ eq 'E' { - my @contents := []; - my @meta := []; - for $/[0] { - if $_ { - @contents.push(~$_); - @meta.push($*W.add_string_constant(~$_).compile_time_value); - #my $s := Perl6::Pod::str_from_entity(~$_); - #$s ?? @contents.push($s) && @meta.push(~$_) - # !! $/.worry("\"$_\" is not a valid HTML5 entity."); - } else { - my $n := $_ - ?? $_.made - !! nqp::codepointfromname(~$_); - if $n >= 0 { - @contents.push(nqp::chr($n)); - @meta.push($n); - } else { - $/.worry("\"$_\" is not a valid Unicode character name or code point."); - } - } - } - @contents := Perl6::Pod::serialize_aos(@contents).compile_time_value; - @meta := Perl6::Pod::serialize_array(@meta).compile_time_value; - make Perl6::Pod::serialize_object( - 'Pod::FormattingCode', - :type($*W.add_string_constant(~$).compile_time_value), - :@contents, - :@meta, - ).compile_time_value; - } else { - my @chars := Perl6::Pod::build_pod_chars($); - my @meta := []; - if $ eq 'X' { - for $/[0] { - my @tmp := []; - for $_ { - @tmp.push(~$_); - } - @meta.push(@tmp); - } - @meta := Perl6::Pod::serialize_aoaos(@meta).compile_time_value; - } else { - for $ { - @meta.push(~$_) - } - @meta := Perl6::Pod::serialize_aos(@meta).compile_time_value; - } - my @contents := Perl6::Pod::build_pod_strings([@chars]); - @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; - my $past := Perl6::Pod::serialize_object( - 'Pod::FormattingCode', - :type($*W.add_string_constant(~$).compile_time_value), - :@contents, - :meta(@meta), - ); - make $past.compile_time_value; - } - } - - method pod_string($/) { - make Perl6::Pod::build_pod_chars($); - } - - method pod_balanced_braces($/) { - if $ { - my @chars := Perl6::Pod::build_pod_chars($); - @chars.unshift(~$); - @chars.push(~$); - make @chars; - } else { - make ~$ - } - } - - method pod_string_character($/) { - if $ { - make $.ast - } elsif $ { - make $.ast - } else { - make ~$; - } - } - - method table_row($/) { - make ~$/ - } - - method table_row_or_blank($/) { - make ~$/ - } - - method unitstart($/) { - # Use SET_BLOCK_OUTER_CTX (inherited from HLL::Actions) - # to set dynamic outer lexical context and namespace details - # for the compilation unit. - self.SET_BLOCK_OUTER_CTX($*UNIT_OUTER); - } - - method statementlist($/) { - my $past := QAST::Stmts.new( :node($/) ); - if $ { - my int $i := 0; - my int $e := nqp::elems($) - 1; - while $i <= $e { - my $ast := $[$i].ast; - if $ast { - if $ast.ann('statement_level') && $*statement_level { - $ast.ann('statement_level')(); - } - if $ast.ann('sink_ast') { - $ast := QAST::Want.new($ast, 'v', $ast.ann('sink_ast')); - $ast := UNWANTED($ast, 'statementlist/sink_ast') if $i < $e; - } - elsif $ast.ann('bare_block') { - if $i < $e { - $ast := UNWANTED(autosink($ast.ann('bare_block')), "statementlist/bare_block"); - } - elsif $*ESCAPEBLOCK { - $ast := WANTED($ast.ann('bare_block'),'statementlist/escape'); - } - else { - $ast := autosink($ast.ann('bare_block')); - } - } - else { - if nqp::istype($ast,QAST::Op) && ($ast.op eq 'while' || $ast.op eq 'until' || $ast.op eq 'repeat_while' || $ast.op eq 'repeat_until') { - $ast := UNWANTED($ast,'statementlist/loop'); # statement level loops never want return value - } - elsif $i == $e && $*ESCAPEBLOCK { - $ast := QAST::Stmt.new(autosink(WANTED($ast,'statementlist/else')), :returns($ast.returns)); - } - else { - $ast := QAST::Stmt.new(autosink($ast), :returns($ast.returns)); - } - } - $ast.node($[$i]); - $past.push( $ast ); - } - ++$i; - } - } - if +$past.list < 1 { - $past.push(QAST::WVal.new( :value($*W.find_symbol(['Nil'])) )); - } - else { - my $pl := $past[+@($past) - 1]; - if $pl.sunk { - $past.push(QAST::WVal.new( :value($*W.find_symbol(['Nil'])) )); - } - else { - $pl.final(1); - $past.returns($pl.returns); - } - } - make $past; - } - - # Produces a LoL from a semicolon list - method semilist($/) { - if $ { - my $past := QAST::Stmts.new( :node($/) ); - if $ > 1 { - my $l := QAST::Op.new( :name('&infix:<,>'), :op('call') ); - for $ { - my $sast := $_.ast || QAST::WVal.new( :value($*W.find_symbol(['Nil'])) ); - $l.push(wanted($sast, 'semilist')); - } - $past.push($l); - $past.annotate('multislice', 1); - } - else { - $past.push($[0].ast || QAST::WVal.new( :value($*W.find_symbol(['Nil'])) )); - } - make $past; - } - else { - make QAST::Op.new( :op('call'), :name('&infix:<,>') ); - } - } - - method sequence($/) { - my $past := QAST::Stmts.new( :node($/) ); - if $ { - for $ { $past.push($_.ast) if $_.ast; } - } - unless +@($past) { - $past.push( QAST::Op.new( :op('call'), :name('&infix:<,>') ) ); - } - make $past; - } - - method statement($/) { - my $past; - if $ { - my $mc := $; - my $ml := $; - $past := $.ast; - if $mc { - if ~$mc eq 'with' { - make thunkity_thunk($/,'.b',QAST::Op.new( :op('call'), :name('&infix:')),[$mc,$]); - return; - } - elsif ~$mc eq 'without' { - make thunkity_thunk($/,'.b',QAST::Op.new( :op('call'), :name('&infix:')),[$mc,$]); - return; - } - my $mc_ast := $mc.ast; - if $past.ann('bare_block') { - my $cond_block := $past.ann('past_block'); - remove_block($*W.cur_lexpad(), $cond_block); - $cond_block.blocktype('immediate'); - $past := $cond_block; - } - $mc_ast.push($past); - $mc_ast.push(QAST::WVal.new( :value($*W.find_symbol(['Empty'])) )); - $past := $mc_ast; - } - if $ml { - $past.okifnil(1); - $past[0].okifnil(1) if +@($past); - my $cond := $ml.ast; - if ~$ml eq 'given' { - unless $past.ann('bare_block') { - $past := make_topic_block_ref($/, $past, migrate_stmt_id => $*STATEMENT_ID); - } - $past := QAST::Op.new( :op('call'), block_closure($past), $cond ); - } - elsif ~$ml eq 'for' { - unless $past.ann('past_block') { - $past := make_topic_block_ref($/, $past, migrate_stmt_id => $*STATEMENT_ID); - } - my $fornode := QAST::Op.new( - :op, :node($/), - $cond, - block_closure($past), - ); - $past := QAST::Want.new( - $fornode, - 'v', QAST::Op.new(:op, $fornode), - ); - $past[2].sunk(1); - my $sinkee := $past[0]; - $past.annotate('statement_level', -> { - UNWANTED($sinkee, 'force for mod'); - $fornode.op('p6forstmt') if can-use-p6forstmt($fornode[1]); - $fornode.annotate('IterationEnd', $*W.find_symbol(['IterationEnd'])); - $fornode.annotate('Nil', $*W.find_symbol(['Nil'])); - }); - } - else { - $past := QAST::Op.new($cond, $past, :op(~$ml), :node($/) ); - } - } - } - elsif $ { $past := $.ast; } - elsif $ { $past := $.ast; } - else { $past := 0; } - - if $past { - my $id := $*STATEMENT_ID; - $past.annotate('statement_id', $id); - - # only trace when running in source - if $/.pragma('trace') && !$*W.is_precompilation_mode { - my $code := ~$/; + # only trace when running in source + if $/.pragma('trace') && !$*W.is_precompilation_mode { + my $code := ~$/; # don't bother putting ops for activating it if $code eq 'use trace' { @@ -2739,13 +2480,20 @@ unless $block.symbol('$!') { $*W.install_lexical_magical($block, '$!'); } - make QAST::Op.new( + my $qast := QAST::Op.new( :op('callmethod'), :name('start'), :returns($*W.find_symbol(['Promise'])), QAST::WVal.new( :value($*W.find_symbol(['Promise'])) ), $.ast ); + unless $*W.lang-ver-before('d') { + $qast.push(QAST::WVal.new( + :value($*W.find_symbol(['Bool', 'True'])), + :named('report-broken-if-sunk') + )); + } + make $qast; } method statement_prefix:sym($/) { @@ -3202,7 +2950,7 @@ :op, :name, :returns($*W.find_symbol(['Slang'])), QAST::Var.new( :name, :scope )); my $g := $/.slang_grammar($desigilname); - $*W.add_object($g); + $*W.add_object_if_no_sc($g); my $a := $/.slang_actions($desigilname); if !nqp::isnull($g) { my $wval := QAST::WVal.new( :value($g) ); @@ -3244,7 +2992,7 @@ } if $name eq '$?LANG' { my $cursor := $/; - $*W.add_object($cursor); + $*W.add_object_if_no_sc($cursor); $past := QAST::WVal.new(:value($cursor)); } elsif $name eq '$?LINE' { @@ -3263,7 +3011,7 @@ if $resources { $past := QAST::WVal.new( :value($resources) ); if nqp::isnull(nqp::getobjsc($resources)) { - $*W.add_object($resources); + $*W.add_object_if_no_sc($resources); } } else { @@ -4064,6 +3812,12 @@ method routine_declarator:sym($/) { make $.ast; } method routine_declarator:sym($/) { make $.ast; } + sub decontrv_op() { + $*W.lang-ver-before('d') && nqp::getcomp('perl6').backend.name eq 'moar' + ?? 'p6decontrv_6c' + !! 'p6decontrv' + } + method routine_def($/) { my $block; @@ -4081,7 +3835,7 @@ } if is_clearly_returnless($block) { $block[1] := QAST::Op.new( - :op('p6decontrv'), + :op(decontrv_op()), QAST::WVal.new( :value($*DECLARAND) ), $block[1]); $block[1] := wrap_return_type_check($block[1], $*DECLARAND); @@ -4514,12 +4268,9 @@ } else { $past := WANTED($.ast,'method_def'); - if $past.ann('placeholder_sig') { - $/.PRECURSOR.panic('Placeholder variables cannot be used in a method'); - } if is_clearly_returnless($past) { $past[1] := QAST::Op.new( - :op('p6decontrv'), + :op(decontrv_op()), QAST::WVal.new( :value($*DECLARAND) ), $past[1]); $past[1] := wrap_return_type_check($past[1], $*DECLARAND); @@ -4565,6 +4316,32 @@ } $past.name($name ?? $name !! ''); + if $past.ann('placeholder_sig') { + my $placeholders := nqp::iterator($past.ann('placeholder_sig')); + my @non-placeholder-names; + my $method-name := $past.name; + while $placeholders { + my $placeholder := nqp::shift($placeholders); + my $name := $placeholder; + my $non-placeholder-name; + if $placeholder || $placeholder { + $non-placeholder-name := nqp::concat('*', $name); + } elsif $placeholder { + $non-placeholder-name := nqp::concat(':', nqp::concat(nqp::substr($name, 0, 1), nqp::substr($name, 2))); + } else { + $non-placeholder-name := nqp::concat(nqp::substr($name, 0, 1), nqp::substr($name, 2)); + } + nqp::push( @non-placeholder-names, $non-placeholder-name); + } + + my $non-placeholder-names := nqp::join(', ', @non-placeholder-names); + + my $first-placeholder := $past.ann('placeholder_sig')[0]; + my $first-placeholder-name := $first-placeholder; + + $first-placeholder.PRECURSOR.panic("Placeholder variables (eg. $first-placeholder-name) cannot be used in a method.\nPlease specify an explicit signature, like $*METHODTYPE $method-name ($non-placeholder-names) \{ ... \}"); + } + my $code := methodize_block($/, $*DECLARAND, $past, $*SIG_OBJ, %*SIG_INFO, :yada(is_yada($/))); @@ -5804,7 +5581,7 @@ if $*NEGATE_VALUE { my $neg-op := $*W.find_symbol(['&prefix:<->']); $val := $neg-op($val); - $*W.add_object($val); + $*W.add_object_if_no_sc($val); } %*PARAM_INFO := $val.WHAT; @@ -8214,7 +7991,7 @@ method version($/) { my $v := $*W.find_symbol(['Version']).new(~$); - $*W.add_object($v); + $*W.add_object_if_no_sc($v); make QAST::WVal.new( :value($v) ); } @@ -8932,7 +8709,7 @@ my $past := $.ast.ann('past_block').pop; nqp::bindattr($quasi_ast, $ast_class, '$!past', $past); nqp::bindattr($quasi_ast, $ast_class, '$!Str', $/.Str()); - $*W.add_object($quasi_ast); + $*W.add_object_if_no_sc($quasi_ast); my $throwaway_block := QAST::Block.new(); my $quasi_context := block_closure( reference_to_code_object( @@ -9672,6 +9449,7 @@ pos_slurpy => $pos_slurpy, named_slurpy => $named_slurpy, placeholder => $full_name, + node => $/, is_multi_invocant => 1, sigil => ~$sigil); @@ -10244,130 +10022,404 @@ $i++; } - # go through any remaining children and just migrate QAST::Blocks - my $qels := nqp::elems($qast); - while $i < $qels { - find_block_calls_and_migrate($cur_lexpad, $curry, $qast[$i]); - $i++; + # go through any remaining children and just migrate QAST::Blocks + my $qels := nqp::elems($qast); + while $i < $qels { + find_block_calls_and_migrate($cur_lexpad, $curry, $qast[$i]); + $i++; + } + + # Bake the signature for our curry + my %sig_info := hash(parameters => @params); + my $signature := $*W.create_signature_and_params: + $/, %sig_info, $curry, 'Mu'; + add_signature_binding_code($curry, $signature, @params); + + fatalize($curry[1]) if $*FATAL; + + # Create a code object for our curry + my $code := $*W.create_code_object: $curry, 'WhateverCode', $signature; + $qast := block_closure(reference_to_code_object($code, $curry)); + $qast.returns: $WhateverCode; + $qast.arity: nqp::elems(@params); + + # Hyperspace! + $qast := QAST::Op.new: :op, :name<&HYPERWHATEVER>, $qast + if $hyperwhatever; + $qast; + } + + sub find_block_calls_and_migrate($from, $to, $qast) { + if nqp::can($qast, 'ann') && $qast.ann('past_block') -> $block { + $to[0].push: $block; + remove_block($from, $block, :ignore-not-found); + } + elsif nqp::istype($qast, QAST::Node) { + for @($qast) { + find_block_calls_and_migrate($from, $to, $_); + } + } + } + + sub remove_block($from, $block, :$ignore-not-found) { + # Remove the QAST::Block $block from $from[0]; die if not found. + my @decls := $from[0].list; + my int $i := 0; + my int $n := nqp::elems(@decls); + while $i < $n { + my $consider := @decls[$i]; + if $consider =:= $block { + @decls[$i] := QAST::Op.new( :op('null') ); + return 1; + } + elsif nqp::istype($consider, QAST::Stmt) || nqp::istype($consider, QAST::Stmts) { + if $consider[0] =:= $block { + $consider[0] := QAST::Op.new( :op('null') ); + return 1; + } + } + $i++; + } + nqp::die('Internal error: failed to remove block') + unless $ignore-not-found; + } + + sub wrap_return_type_check($wrappee, $code_obj) { + my $ret := %*SIG_INFO; + return $wrappee if nqp::isconcrete($ret) || $ret.HOW.name($ret) eq 'Nil'; + QAST::Op.new( + :op('p6typecheckrv'), + $wrappee, + QAST::WVal.new( :value($code_obj) ), + QAST::WVal.new( :value($*W.find_symbol(['Nil'])) ) + ); + } + + sub wrap_return_handler($past) { + wrap_return_type_check( + QAST::Op.new( + :op, + # If we fall off the bottom, decontainerize if + # rw not set. + QAST::Op.new( :op(decontrv_op()), QAST::WVal.new( :value($*DECLARAND) ), $past ), + 'RETURN', + QAST::Op.new( :op ) + ), + $*DECLARAND + ) + } + + # Works out how to look up a type. If it's not generic and is in an SC, we + # statically resolve it. Otherwise, we punt to a runtime lexical lookup. + sub instantiated_type(@name, $/) { + CATCH { + $*W.throw($/, ['X', 'NoSuchSymbol'], symbol => join('::', @name)); + } + my $type := $*W.find_symbol(@name); + my $is_generic := 0; + try { $is_generic := $type.HOW.archetypes.generic } + my $past; + if $is_generic || nqp::isnull(nqp::getobjsc($type)) || istype($type.HOW,$/.how('package')) { + $past := $*W.symbol_lookup(@name, $/); + $past.set_compile_time_value($type); + } + else { + $past := QAST::WVal.new( :value($type) ); + } + $past.returns($type.WHAT); + $past + } + + # Ensures that the given PAST node has a value known at compile + # time and if so obtains it. Otherwise reports an error, involving + # the $usage parameter to make it more helpful. + sub compile_time_value_str($past, $usage, $/) { + if $past.has_compile_time_value { + nqp::unbox_s($past.compile_time_value); + } + else { + $*W.throw($/, ['X', 'Value', 'Dynamic'], what => $usage); + } + } + + sub istype($val, $type) { + try { return nqp::istype($val, $type) } + 0 + } + + #================================================================ + # POD-ONLY CODE HANDLERS + #================================================================ + # move ALL Pod-only action objects here + + method pod_content_toplevel($/) { + my $child := $.ast; + # make sure we don't push the same thing twice + if $child { + my $id := $/.from ~ "," ~ ~$/.to; + if !$*POD_BLOCKS_SEEN{$id} { + $*POD_BLOCKS.push($child); + $*POD_BLOCKS_SEEN{$id} := 1; + } + } + make $child; + } + + method pod_content:sym($/) { + make $.ast; + } + + # TODO The spaces arg from Grammar.nqp seems + # NOT to be handled. That shows up + # in testing for config continuation lines. + method pod_configuration($/) { + make Perl6::Pod::make_config($/); + } + + method pod_block:sym($/) { + if $.Str ~~ /^defn/ { + make Perl6::Pod::defn($/, $delim-block); + } + else { + make Perl6::Pod::any_block($/, $delim-block); + } + } + + method pod_block:sym($/) { + make Perl6::Pod::raw_block($/); + } + + method pod_block:sym($/) { + make Perl6::Pod::table($/, $delim-block); + } + + method pod_block:sym($/) { + # TODO add numbered-alias handling + my $config := $.ast; + my @contents := $.ast; + @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; + make Perl6::Pod::serialize_object('Pod::Block::Code', + :@contents,:$config).compile_time_value + } + + method delimited_code_content($/) { + my @contents := []; + for $/[0] { + if $_ { + nqp::splice(@contents, + Perl6::Pod::pod_strings_from_matches($_), + +@contents, 0); + nqp::push(@contents, $*W.add_constant( + 'Str', 'str', ~$_ + ).compile_time_value); + } else { + @contents.push($*W.add_constant('Str', 'str', "\n").compile_time_value); + } + } + make @contents; + } + + method pod_block:sym($/) { + if $.Str ~~ /^defn/ { + make Perl6::Pod::defn($/, $para-block); + } + else { + make Perl6::Pod::any_block($/, $para-block); + } + } + + method pod_block:sym($/) { + make Perl6::Pod::raw_block($/); + } + + method pod_block:sym($/) { + make Perl6::Pod::table($/, $para-block); + } + + method pod_block:sym($/) { + # TODO make config via call to make_config in Pod.nqp + my $config := $.ast; + my @contents := []; + for $ { + nqp::splice(@contents, $_.ast, +@contents, 0); + } + @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; + make Perl6::Pod::serialize_object('Pod::Block::Code', + :@contents,:$config).compile_time_value; + } + + method pod_block:sym($/) { + if $.Str ~~ /^defn/ { + make Perl6::Pod::defn($/, $abbrev-block); } + else { + make Perl6::Pod::any_block($/, $abbrev-block); + } + } - # Bake the signature for our curry - my %sig_info := hash(parameters => @params); - my $signature := $*W.create_signature_and_params: - $/, %sig_info, $curry, 'Mu'; - add_signature_binding_code($curry, $signature, @params); + method pod_block:sym($/) { + make Perl6::Pod::raw_block($/); + } - fatalize($curry[1]) if $*FATAL; + method pod_block:sym($/) { + make Perl6::Pod::table($/, $abbrev-block); + } - # Create a code object for our curry - my $code := $*W.create_code_object: $curry, 'WhateverCode', $signature; - $qast := block_closure(reference_to_code_object($code, $curry)); - $qast.returns: $WhateverCode; - $qast.arity: nqp::elems(@params); + method pod_block:sym($/) { + my @contents := []; + for $ { + nqp::splice(@contents, $_.ast, +@contents, 0); + } + @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; + make Perl6::Pod::serialize_object( + 'Pod::Block::Code', :@contents + ).compile_time_value + } - # Hyperspace! - $qast := QAST::Op.new: :op, :name<&HYPERWHATEVER>, $qast - if $hyperwhatever; - $qast; + method pod_line ($/) { + my @contents := Perl6::Pod::pod_strings_from_matches($); + @contents.push($*W.add_constant( + 'Str', 'str', ~$ + ).compile_time_value); + make @contents; } - sub find_block_calls_and_migrate($from, $to, $qast) { - if nqp::can($qast, 'ann') && $qast.ann('past_block') -> $block { - $to[0].push: $block; - remove_block($from, $block, :ignore-not-found); - } - elsif nqp::istype($qast, QAST::Node) { - for @($qast) { - find_block_calls_and_migrate($from, $to, $_); - } + method pod_block:sym($/) { + $*W.install_lexical_symbol( + $*UNIT,'$=finish', nqp::hllizefor(~$, 'perl6')); + } + + method pod_content:sym($/) { + make Perl6::Pod::config($/); + } + + method pod_content:sym($/) { + my @ret := []; + for $ { + @ret.push($_.ast); } + my $past := Perl6::Pod::serialize_array(@ret); + make $past.compile_time_value; } - sub remove_block($from, $block, :$ignore-not-found) { - # Remove the QAST::Block $block from $from[0]; die if not found. - my @decls := $from[0].list; - my int $i := 0; - my int $n := nqp::elems(@decls); - while $i < $n { - my $consider := @decls[$i]; - if $consider =:= $block { - @decls[$i] := QAST::Op.new( :op('null') ); - return 1; + method pod_textcontent:sym($/) { + my @contents := Perl6::Pod::pod_strings_from_matches($); + @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; + make Perl6::Pod::serialize_object('Pod::Block::Para', :@contents).compile_time_value + } + + method pod_textcontent:sym($/) { + my $s := $.Str; + my $t := subst($.Str, /\n$s/, "\n", :global); + $t := subst($t, /\n$/, ''); # chomp! + my $past := Perl6::Pod::serialize_object( + 'Pod::Block::Code', + :contents(Perl6::Pod::serialize_aos([$t]).compile_time_value), + ); + make $past.compile_time_value; + } + + method pod_formatting_code($/) { + if $ eq 'V' { + make ~$; + } elsif $ eq 'E' { + my @contents := []; + my @meta := []; + for $/[0] { + if $_ { + @contents.push(~$_); + @meta.push($*W.add_string_constant(~$_).compile_time_value); + #my $s := Perl6::Pod::str_from_entity(~$_); + #$s ?? @contents.push($s) && @meta.push(~$_) + # !! $/.worry("\"$_\" is not a valid HTML5 entity."); + } else { + my $n := $_ + ?? $_.made + !! nqp::codepointfromname(~$_); + if $n >= 0 { + @contents.push(nqp::chr($n)); + @meta.push($n); + } else { + $/.worry("\"$_\" is not a valid Unicode character name or code point."); + } + } } - elsif nqp::istype($consider, QAST::Stmt) || nqp::istype($consider, QAST::Stmts) { - if $consider[0] =:= $block { - $consider[0] := QAST::Op.new( :op('null') ); - return 1; + @contents := Perl6::Pod::serialize_aos(@contents).compile_time_value; + @meta := Perl6::Pod::serialize_array(@meta).compile_time_value; + make Perl6::Pod::serialize_object( + 'Pod::FormattingCode', + :type($*W.add_string_constant(~$).compile_time_value), + :@contents, + :@meta, + ).compile_time_value; + } else { + my @chars := Perl6::Pod::build_pod_chars($); + my @meta := []; + if $ eq 'X' { + for $/[0] { + my @tmp := []; + for $_ { + @tmp.push(~$_); + } + @meta.push(@tmp); + } + @meta := Perl6::Pod::serialize_aoaos(@meta).compile_time_value; + } else { + for $ { + @meta.push(~$_) } + @meta := Perl6::Pod::serialize_aos(@meta).compile_time_value; } - $i++; + my @contents := Perl6::Pod::build_pod_strings([@chars]); + @contents := Perl6::Pod::serialize_array(@contents).compile_time_value; + my $past := Perl6::Pod::serialize_object( + 'Pod::FormattingCode', + :type($*W.add_string_constant(~$).compile_time_value), + :@contents, + :meta(@meta), + ); + make $past.compile_time_value; } - nqp::die('Internal error: failed to remove block') - unless $ignore-not-found; } - sub wrap_return_type_check($wrappee, $code_obj) { - my $ret := %*SIG_INFO; - return $wrappee if nqp::isconcrete($ret) || $ret.HOW.name($ret) eq 'Nil'; - QAST::Op.new( - :op('p6typecheckrv'), - $wrappee, - QAST::WVal.new( :value($code_obj) ), - QAST::WVal.new( :value($*W.find_symbol(['Nil'])) ) - ); + method pod_string($/) { + make Perl6::Pod::build_pod_chars($); } - sub wrap_return_handler($past) { - wrap_return_type_check( - QAST::Op.new( - :op, - # If we fall off the bottom, decontainerize if - # rw not set. - QAST::Op.new( :op('p6decontrv'), QAST::WVal.new( :value($*DECLARAND) ), $past ), - 'RETURN', - QAST::Op.new( :op ) - ), - $*DECLARAND - ) + method pod_balanced_braces($/) { + if $ { + my @chars := Perl6::Pod::build_pod_chars($); + @chars.unshift(~$); + @chars.push(~$); + make @chars; + } else { + make ~$ + } } - # Works out how to look up a type. If it's not generic and is in an SC, we - # statically resolve it. Otherwise, we punt to a runtime lexical lookup. - sub instantiated_type(@name, $/) { - CATCH { - $*W.throw($/, ['X', 'NoSuchSymbol'], symbol => join('::', @name)); - } - my $type := $*W.find_symbol(@name); - my $is_generic := 0; - try { $is_generic := $type.HOW.archetypes.generic } - my $past; - if $is_generic || nqp::isnull(nqp::getobjsc($type)) || istype($type.HOW,$/.how('package')) { - $past := $*W.symbol_lookup(@name, $/); - $past.set_compile_time_value($type); - } - else { - $past := QAST::WVal.new( :value($type) ); + method pod_string_character($/) { + if $ { + make $.ast + } elsif $ { + make $.ast + } else { + make ~$; } - $past.returns($type.WHAT); - $past } - # Ensures that the given PAST node has a value known at compile - # time and if so obtains it. Otherwise reports an error, involving - # the $usage parameter to make it more helpful. - sub compile_time_value_str($past, $usage, $/) { - if $past.has_compile_time_value { - nqp::unbox_s($past.compile_time_value); - } - else { - $*W.throw($/, ['X', 'Value', 'Dynamic'], what => $usage); - } + method table_row($/) { + make ~$/ } - sub istype($val, $type) { - try { return nqp::istype($val, $type) } - 0 + method table_row_or_blank($/) { + make ~$/ } + + + + #================================================================ + # end of class Perl6::Actions block + #================================================================ } class Perl6::QActions is HLL::Actions does STDActions { @@ -10467,7 +10519,7 @@ if $thisq.has_compile_time_value { try { my $result := $*W.find_symbol(['&val'])($thisq.compile_time_value); - $*W.add_object($result); + $*W.add_object_if_no_sc($result); nqp::push(@results, QAST::WVal.new(:value($result), :node($/))); CATCH { nqp::push(@results, $thisq) } @@ -10483,7 +10535,7 @@ } elsif $qast.has_compile_time_value { # a single string that we can handle try { my $result := $*W.find_symbol(['&val'])($qast.compile_time_value); - $*W.add_object($result); + $*W.add_object_if_no_sc($result); $qast := QAST::WVal.new(:value($result)); CATCH { } diff -Nru rakudo-2018.10/src/Perl6/Compiler.nqp rakudo-2018.12/src/Perl6/Compiler.nqp --- rakudo-2018.10/src/Perl6/Compiler.nqp 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/Perl6/Compiler.nqp 2018-12-21 05:16:35.000000000 +0000 @@ -4,6 +4,7 @@ class Perl6::Compiler is HLL::Compiler { has $!language_version; + has $!can_language_versions; method compilation-id() { my class IDHolder { } @@ -24,9 +25,14 @@ $!language_version } else { - $!language_version := self.config + $!language_version := self.config } } + method can_language_versions() { + $!can_language_versions + ?? $!can_language_versions + !! ($!can_language_versions := self.config) + } method command_eval(*@args, *%options) { if nqp::existskey(%options, 'doc') && !%options { diff -Nru rakudo-2018.10/src/Perl6/Grammar.nqp rakudo-2018.12/src/Perl6/Grammar.nqp --- rakudo-2018.10/src/Perl6/Grammar.nqp 2018-10-28 21:51:17.000000000 +0000 +++ rakudo-2018.12/src/Perl6/Grammar.nqp 2018-12-21 05:16:35.000000000 +0000 @@ -473,6 +473,9 @@ } grammar Perl6::Grammar is HLL::Grammar does STD { + #================================================================ + # AMBIENT AND POD-COMMON CODE HANDLERS + #================================================================ my class SerializationContextId { my $count := 0; my $lock := NQPLock.new; @@ -714,1488 +717,961 @@ ] } - proto token comment { <...> } - - token comment:sym<#> { - '#' {} \N* - } + token install_doc_phaser { } - token comment:sym<#`(...)> { - '#`' {} - [ <.quibble(self.slang_grammar('Quote'))> || <.typed_panic: 'X::Syntax::Comment::Embedded'> ] + token vnum { + \w+ | '*' } - token comment:sym<#|(...)> { - '#|' - { - unless $*POD_BLOCKS_SEEN{ self.from() } { - $*POD_BLOCKS_SEEN{ self.from() } := 1; - if $*DECLARATOR_DOCS eq '' { - $*DECLARATOR_DOCS := $; - } else { - $*DECLARATOR_DOCS := nqp::concat($*DECLARATOR_DOCS, nqp::concat("\n", $)); - } - } - } + token version { + 'v' $=[+ % '.' '+'?] + # cheat because of LTM fail } - token comment:sym<#|> { - '#|' \h+ $=[\N*] - { - unless $*POD_BLOCKS_SEEN{ self.from() } { - $*POD_BLOCKS_SEEN{ self.from() } := 1; - if $*DECLARATOR_DOCS eq '' { - $*DECLARATOR_DOCS := $; - } else { - $*DECLARATOR_DOCS := nqp::concat($*DECLARATOR_DOCS, nqp::concat("\n", $)); - } - } - } - } + ## Top-level rules - token comment:sym<#=(...)> { - '#=' - { - self.attach_trailing_docs(~$); - } - } + token comp_unit { + # From STD.pm. + :my $*LEFTSIGIL; # sigil of LHS for item vs list assignment + :my $*SCOPE := ''; # which scope declarator we're under + :my $*MULTINESS := ''; # which multi declarator we're under + :my $*QSIGIL := ''; # sigil of current interpolation + :my $*IN_META := ''; # parsing a metaoperator like [..] + :my $*IN_REDUCE := 0; # attempting to parse an [op] construct + :my $*IN_DECL; # what declaration we're in + :my $*IN_RETURN := 0; # are we in a return? + :my $*HAS_SELF := ''; # is 'self' available? (for $.foo style calls) + :my $*begin_compunit := 1; # whether we're at start of a compilation unit + :my $*DECLARAND; # the current thingy we're declaring, and subject of traits + :my $*CODE_OBJECT; # the code object we're currently inside + :my $*METHODTYPE; # the current type of method we're in, if any + :my $*PKGDECL; # what type of package we're in, if any + :my %*MYSTERY; # names we assume may be post-declared functions + :my $*BORG := {}; # who gets blamed for a missing block + :my $*CCSTATE := ''; + :my $*STRICT; + :my $*INVOCANT_OK := 0; + :my $*INVOCANT; + :my $*ARG_FLAT_OK := 0; + :my $*WHENEVER_COUNT := -1; # -1 indicates whenever not valid here - token comment:sym<#=> { - '#=' \h+ $=[\N*] - { - self.attach_trailing_docs(~$); - } - } + # Error related. There are three levels: worry (just a warning), sorry + # (fatal but not immediately so) and panic (immediately deadly). There + # is a limit on the number of sorrows also. Unlike STD, which emits the + # textual messages as it goes, we keep track of the exception objects + # and, if needed, make a composite exception group. + :my @*WORRIES; # exception objects resulting from worry + :my @*SORROWS; # exception objects resulting from sorry + :my $*SORRY_LIMIT := 10; # when sorrow turns to panic - method attach_leading_docs() { - # TODO allow some limited text layout here - if ~$*DOC ne '' { - my $cont := Perl6::Pod::serialize_aos( - [Perl6::Pod::normalize_text(~$*DOC)] - ).compile_time_value; - my $block := $*W.add_constant( - 'Pod::Block::Declarator', 'type_new', - :nocache, :leading([$cont]), - ); - $*POD_BLOCK := $block.compile_time_value; - $*POD_BLOCKS.push($*POD_BLOCK); - } - self - } + # Extras. + :my @*NQP_VIOLATIONS; # nqp::ops per line number + :my %*HANDLERS; # block exception handlers + :my $*IMPLICIT; # whether we allow an implicit param + :my $*HAS_YOU_ARE_HERE := 0; # whether {YOU_ARE_HERE} has shown up + :my $*OFTYPE; + :my $*VMARGIN := 0; # pod stuff + :my $*ALLOW_INLINE_CODE := 0; # pod stuff + :my $*POD_IN_CODE_BLOCK := 0; # pod stuff + :my $*POD_IN_FORMATTINGCODE := 0; # pod stuff + :my $*POD_ALLOW_FCODES := 0b11111111111111111111111111; # allow which fcodes? + :my $*POD_ANGLE_COUNT := 0; # pod stuff + :my $*IN_REGEX_ASSERTION := 0; + :my $*IN_PROTO := 0; # are we inside a proto? + :my $*NEXT_STATEMENT_ID := 1; # to give each statement an ID + :my $*IN_STMT_MOD := 0; # are we inside a statement modifier? + :my $*COMPILING_CORE_SETTING := 0; # are we compiling CORE.setting? + # TODO XXX: see https://github.com/rakudo/rakudo/issues/2432 + :my $*SET_DEFAULT_LANG_VER := 1; + :my %*SIG_INFO; # information about recent signature - method attach_trailing_docs($doc) { - # TODO allow some limited text layout here - unless $*POD_BLOCKS_SEEN{ self.from() } { - $*POD_BLOCKS_SEEN{ self.from() } := 1; - my $pod_block; - if $doc ne '' { - my $cont := Perl6::Pod::serialize_aos( - [Perl6::Pod::normalize_text($doc)] - ).compile_time_value; - my $block := $*W.add_constant( - 'Pod::Block::Declarator', 'type_new', - :nocache, :trailing([$cont]), - ); - $pod_block := $block.compile_time_value; - } - unless $*PRECEDING_DECL =:= Mu { - Perl6::Pod::document(self.MATCH, $*PRECEDING_DECL, $pod_block, :trailing); - } - } - } + # Various interesting scopes we'd like to keep to hand. + :my $*GLOBALish; + :my $*PACKAGE; + :my $*UNIT; + :my $*UNIT_OUTER; + :my $*EXPORT; + # stack of packages, which the 'is export' needs + :my @*PACKAGES := []; - token pod_content_toplevel { - - } + # A place for Pod + :my $*POD_BLOCKS := []; + :my $*POD_BLOCKS_SEEN := {}; + :my $*POD_PAST; + :my $*DECLARATOR_DOCS; + :my $*PRECEDING_DECL; # for #= comments + :my $*PRECEDING_DECL_LINE := -1; # XXX update this when I see another comment like it? + # TODO use these vars to implement S26 pod data block handling + :my $*DATA-BLOCKS := []; + :my %*DATA-BLOCKS := {}; - proto token pod_content { <...> } + # Quasis and unquotes + :my $*IN_QUASI := 0; # whether we're currently in a quasi block + :my $*MAIN := 'MAIN'; - token pod_content:sym { - * - - * - } + # performance improvement stuff + :my $*FAKE_INFIX_FOUND := 0; - # any number of paragraphs of text - # the paragraphs are separated by one - # or more pod_newlines - # each paragraph originally could have - # consisted of more than one line of - # text that were subsequently squeezed - # into one line - token pod_content:sym { - * + # for runaway detection + :my $*LASTQUOTE := [0,0]; - # TODO get first line if IN-DEFN-BLOCK - + % + + { + nqp::getcomp('perl6').reset_language_version(); + $*W.loading_and_symbol_setup($/) + } - * - } + <.finishpad> + <.bom>? + + - # not a block, just a directive - token pod_content:sym { - * - ^^ \h* '=config' \h+ $=\S+ - + - } + <.install_doc_phaser> - proto token pod_textcontent { <...> } + [ $ || <.typed_panic: 'X::Syntax::Confused'> ] - # for non-code (i.e., regular) text - token pod_textcontent:sym { - $=[ \h* ] - .to - $.from) <= $*VMARGIN }> + <.explain_mystery> + <.cry_sorrows> - $ = [ - \h* [ | $ ] - ] + + { $*W.mop_up_and_check($/) } } - token pod_textcontent:sym { - $=[ \h* ] - .to - $.from) > $*VMARGIN }> + method clonecursor() { + my $new := self.'!cursor_init'( + self.orig(), + :p(self.pos()), + :shared(self.'!shared'()), + :braid(self."!braid"()."!clone"())); + $new; + } - # TODO get first line if IN-DEFN-BLOCK - $ = [ - [ \N+]+ % [+ $] + rule lang-version { + :my $comp := nqp::getcomp('perl6'); + [ + <.ws>? 'use' {} # <-- update $/ so we can grab $ + # we parse out the numeral, since we could have "6d" + :my $version := nqp::radix(10,$[0],0,0)[0]; + [ + || { $*W.load-lang-ver: $, $comp } + || { $/.typed_panic: 'X::Language::Unsupported', + version => ~$ } + ] + || { + # This is the path we take when the user did not + # provide any `use v6.blah` lang version statement + $*W.load-lang-ver: 'v6', $comp if $*SET_DEFAULT_LANG_VER; + } ] } - token pod_formatting_code { - :my $*POD_ALLOW_FCODES := nqp::getlexdyn('$*POD_ALLOW_FCODES'); - :my $*POD_IN_FORMATTINGCODE := nqp::getlexdyn('$*POD_IN_FORMATTINGCODE'); - :my $*POD_ANGLE_COUNT := nqp::getlexdyn('$*POD_ANGLE_COUNT'); - + rule statementlist($*statement_level = 0) { + :my $*LANG; + :my $*LEAF; + :my %*LANG := self.shallow_copy(self.slangs); # XXX deprecated + :my $*STRICT := nqp::getlexdyn('$*STRICT'); - :my $endtag; - - $=['<'+ | '«'] { $*POD_IN_FORMATTINGCODE := 1 } - .Str) - nqp::ord("A"); - if !($*POD_ALLOW_FCODES +& (2 ** $codenum)) { - 0 - } elsif ~$ eq '«' { - $endtag := "»"; - $*POD_ANGLE_COUNT := -1; - 1 - } else { - my int $ct := nqp::chars($); - $endtag := nqp::x(">", $ct); - my $rv := $*POD_ANGLE_COUNT <= 0 || $*POD_ANGLE_COUNT >= $ct; - $*POD_ANGLE_COUNT := $ct; - $rv; - } - }> - { - if $.Str eq "V" || $.Str eq "C" { - $*POD_ALLOW_FCODES := 0; - } - } - [ eq 'E'}> - $=[ - - [ ne 'L' && $ ne 'D' && $ ne 'X' }> || ] - - ]* - ]? - [ - | eq 'L'}> \s* \| \s* $=[.]+ - | eq 'X'}> \s* \| \s* ( [$=[ >.]+] +%% \, ) +%% \; - | eq 'D'}> \s* \| \s* [$=[.]+] +%% \; - | eq 'E'}> ( | $=<[A..Z\s]>+ || $=<[A..Za..z]>+ ) +%% \; - ]? - [ $endtag || <.worry: "Pod formatting code $ missing endtag '$endtag'."> ] - } - - token pod_balanced_braces { - - :my $endtag; + :dba('statement list') +# <.check_LANG_oopsies('statementlist')> + <.ws> + # Define this scope to be a new language. + [ - $=[ - || '<'+ - || '>'+ ]> - ] - ) < $*POD_ANGLE_COUNT || $*POD_ANGLE_COUNT < 0 }> - || - = 1 }> - $=['<'+] - ) == $*POD_ANGLE_COUNT || $*POD_ANGLE_COUNT < 0 }> - { - $endtag := nqp::x(">", nqp::chars($)); - } - $=[ *?] - '> $=[$endtag] + | $ + | > + | [ <.eat_terminator> ]* ] + <.set_braid_from(self)> # any language tweaks must not escape + } - token pod_string { - + + method shallow_copy(%hash) { + my %result; + for %hash { + %result{$_.key} := $_.value; + } + %result } - token pod_string_character { - || || $=[ \N || [ - \n [ - > || - - ] - ] + rule semilist { + :dba('list composer') + '' + [ + | > + | [<.eat_terminator> ]* ] } - proto token pod_block { <...> } - - token pod_configuration($spaces = '') { - [ [\n $spaces '=']? \h+ ]* - } - - token pod_block:sym { - ^^ - $ = [ \h* ] - '=begin' \h+ 'comment' {} - )> + + rule sequence { + :dba('sequence of statements') + '' [ - $ = [ .*? ] - ^^ $ '=end' \h+ - [ - 'comment' [ | $ ] - || $=? { - $/.typed_panic: 'X::Syntax::Pod::BeginWithoutEnd', - type => 'comment', - spaces => ~$, - instead => $ ?? ~$ !! '' - } - ] + | > + | [<.eat_terminator> ]* ] } - regex pod_block:sym { - ^^ - $ = [ \h* ] - '=begin' - [ - <.typed_panic('X::Syntax::Pod::BeginWithoutIdentifier')> - ]? - \h+ + token label { + ':' <.ws> { - $*VMARGIN := $.to - $.from; - } - :my $*ALLOW_INLINE_CODE := 0; - $ = [ - { - $*ALLOW_INLINE_CODE := 1; + $*LABEL := ~$; + if $*W.already_declared('my', self.package, $*W.cur_lexpad(), [$*LABEL]) { + $*W.throw($/, ['X', 'Redeclaration'], symbol => $*LABEL); } - || - ] - :my $*POD_ALLOW_FCODES := nqp::getlexdyn('$*POD_ALLOW_FCODES'); - )> + - [ - # TODO need first line to check for ws-separated '#' - * - ^^ $ '=end' \h+ - [ - $ [ | $ ] - || $=? { - $/.typed_panic: 'X::Syntax::Pod::BeginWithoutEnd', - type => ~$, - spaces => ~$, - instead => $ ?? ~$ !! '' - } - ] - ] + my str $orig := self.orig(); + my int $total := nqp::chars($orig); + my int $from := self.MATCH.from(); + my int $to := self.MATCH.to() + nqp::chars($*LABEL); + my int $line := HLL::Compiler.lineof($orig, self.from(), :cache(1)); + my str $prematch := nqp::substr($orig, $from > 20 ?? $from - 20 !! 0, $from > 20 ?? 20 !! $from); + my str $postmatch := nqp::substr($orig, $to, 20); + my $label := $*W.find_symbol(['Label']).new( :name($*LABEL), :$line, :$prematch, :$postmatch ); + $*W.add_object_if_no_sc($label); + $*W.install_lexical_symbol($*W.cur_lexpad(), $*LABEL, $label); + } } + token statement($*LABEL = '') { + :my $*QSIGIL := ''; + :my $*SCOPE := ''; - token pod_block:sym { - ^^ - $ = [ \h* ] - '=begin' \h+ 'table' {} - :my $*POD_ALLOW_FCODES := nqp::getlexdyn('$*POD_ALLOW_FCODES'); - )> + - [ - [ $=<.table_row_or_blank> ]* - ^^ \h* '=end' \h+ - [ - 'table' [ | $ ] - || $=? { - $/.typed_panic: 'X::Syntax::Pod::BeginWithoutEnd', - type => 'table', - spaces => ~$, - instead => $ ?? ~$ !! '' - } - ] - ] - } + # NOTE: annotations that use STATEMENT_ID often also need IN_STMT_MOD annotation, in order + # to correctly migrate QAST::Blocks in constructs inside topics of statement modifiers + :my $*STATEMENT_ID := $*NEXT_STATEMENT_ID++; + :my $*IN_STMT_MOD := nqp::getlexdyn('$*IN_STMT_MOD'); - # There are several different identifiers for pod blocks - # that are treated essentially the same: 'code', 'input', - # and 'output'. - token pod-delim-code-typ { code | input | output } - token pod_block:sym { - ^^ - $ = [ \h* ] - '=begin' \h+ $= {} - :my $*POD_ALLOW_FCODES := 0; - :my $*POD_IN_CODE_BLOCK := 1; - :my $*POD_DELIMITED_CODE_BLOCK := 1; - )> + + :my $*ESCAPEBLOCK := 0; + :my $actions := self.slang_actions('MAIN'); + + | $ > + + [ - || )> $ '=end' \h+ - [ $= [ | $ ] - { if ~$ ne ~$ { - $/.typed_panic: 'X::Syntax::Pod::BeginWithoutEnd', - type => ~$, - spaces => ~$, - instead => $ ?? ~$ !! '' - }} - || $=? { - $/.typed_panic: 'X::Syntax::Pod::BeginWithoutEnd', - type => $, - spaces => ~$, - instead => $ ?? ~$ !! '' - } - ] + |