Skip to content

Commit

Permalink
Make v6.* work again.
Browse files Browse the repository at this point in the history
- Also modifications like v6.*.*, or v6.a+, or v6.e.* or anything else
what Version accepts would work as expected. Contrary to incorrect
behavior of older releases now the highest version available will be
used. If compiler supports modifiers for a revision they are ignored
unless a three-part version is used. I.e.

use v6.*;

Would load 6.d. But

use v6.*.*;

would load 6.e.PREVIEW.

- Added `whatever` attribute to Version object. Similarly to `plus` it
indicates that version has a Whatver part.

- Added `language_modifier` attribute to Perl6::Compiler
  • Loading branch information
vrurg committed Jun 6, 2019
1 parent bd2ceef commit e51d2ad
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 16 deletions.
8 changes: 8 additions & 0 deletions src/Perl6/Compiler.nqp
Expand Up @@ -4,6 +4,7 @@ use Perl6::Optimizer;

class Perl6::Compiler is HLL::Compiler {
has $!language_version; # Default language version in form 6.c
has $!language_modifier; # Active language modifier; PREVIEW mostly.
has $!language_revisions; # Hash of language revision letters. See gen/<vm>/main-version.nqp
has $!can_language_versions; # List of valid language version

Expand All @@ -17,10 +18,14 @@ class Perl6::Compiler is HLL::Compiler {
method language_name() { 'Perl' }
method reset_language_version() {
$!language_version := NQPMu;
$!language_modifier := NQPMu;
}
method set_language_version($version) {
$!language_version := $version;
}
method set_language_modifier($modifier) {
$!language_modifier := $modifier;
}
method language_version() {
if nqp::defined($!language_version) {
$!language_version
Expand All @@ -29,6 +34,9 @@ class Perl6::Compiler is HLL::Compiler {
$!language_version := self.config<language-version>
}
}
method language_modifier() {
$!language_modifier
}
method can_language_versions() {
$!can_language_versions
?? $!can_language_versions
Expand Down
33 changes: 27 additions & 6 deletions src/Perl6/World.nqp
Expand Up @@ -563,10 +563,14 @@ class Perl6::World is HLL::World {

my str $version := ~$ver-match;
my @vparts := nqp::split('.', $version);
my $vWhatever := nqp::isge_i(nqp::index($version, '*'), 0);
my $vPlus := nqp::isge_i(nqp::index($version, '+'), 0);
my $default_rev := nqp::substr($comp.config<language-version>, 2, 1);

# Do we have dot-splitted version string?
if ((@vparts > 1) && nqp::iseq_s(@vparts[0], 'v6')) || ($version eq 'v6') {
if !($vWhatever || $vPlus) &&
( ((@vparts > 1) && nqp::iseq_s(@vparts[0], 'v6'))
|| ($version eq 'v6') ) {
my $revision := @vparts[1] || $default_rev;
my $lang_ver := '6.' ~ $revision;

Expand All @@ -589,16 +593,33 @@ class Perl6::World is HLL::World {

my $Version := self.find_symbol: ['Version'];
my $vWant := $ver-match.ast.compile_time_value;
my $rev := $vWant.parts.AT-POS(1);
my str $rev_mod := $vWant.parts.elems > 2 ?? $vWant.parts.AT-POS(2) !! '';
my $vWantElems := $vWant.parts.elems;
my %lang_rev := $comp.language_revisions;
unless $vWhatever || $vWant.plus {
# It makes no sense checking for modifier when something like v6.* or v6.c+ is wanted.
my $rev := $vWant.parts.AT-POS(1);
my str $rev_mod := $vWantElems > 2 ?? $vWant.parts.AT-POS(2) !! '';
self."!check-version-modifier"($ver-match, $rev, $rev_mod, $comp);
}

self."!check-version-modifier"($ver-match, $rev, $rev_mod, $comp);
my @can_ver_reversed;
for $comp.can_language_versions { nqp::unshift(@can_ver_reversed, $_) }

for $comp.can_language_versions -> $can-ver {
for @can_ver_reversed -> $can-ver {
# Skip if tried version doesn't match the wanted one
next unless $vWant.ACCEPTS: my $vCan := $Version.new: $can-ver;

my $vCanElems := $vCan.parts.elems;
my $can_rev := $vCan.parts.AT-POS: 1;
$comp.set_language_version: '6.' ~ $can_rev;

# Skip if number of parts in wanted version is different. For example, 6.e.PREVIEW would be skipped for 6.*
# Skip if revision with a required modifier unless explicitly asked for
next if nqp::isne_i($vWantElems, $vCanElems)
|| (nqp::iseq_i($vWantElems, 2)
&& nqp::existskey(%lang_rev{$can_rev}, 'require'));

$comp.set_language_version: '6.' ~ $can_rev;
$comp.set_language_modifier: $vCan.parts.AT-POS: 2 if $vCanElems > 2;

if $can_rev eq 'c' {
$*CAN_LOWER_TOPIC := 0;
Expand Down
23 changes: 14 additions & 9 deletions src/core/Version.pm6
@@ -1,25 +1,27 @@
class Version {
has $!parts;
has int $!plus;
has int $!whatever;
has str $!string;

method !SET-SELF(\parts,\plus,\string) {
method !SET-SELF(\parts,\plus,\whatever,\string) {
$!parts := nqp::getattr(parts,List,'$!reified');
$!plus = plus;
$!whatever = whatever;
$!string = string;
self
}

multi method new(Version:) {
# "v" highlander
INIT nqp::create(Version)!SET-SELF(nqp::list,0,"") # should be once
INIT nqp::create(Version)!SET-SELF(nqp::list,0,0,"") # should be once
}
multi method new(Version: Whatever) {
# "v*" highlander
INIT nqp::create(Version)!SET-SELF(nqp::list(*),-1,"*") # should be once
INIT nqp::create(Version)!SET-SELF(nqp::list(*),-1,1,"*") # should be once
}
multi method new(Version: @parts, Str:D $string, Int() $plus = 0) {
nqp::create(self)!SET-SELF(@parts.eager,$plus,$string)
multi method new(Version: @parts, Str:D $string, Int() $plus = 0, Int() $whatever = 0) {
nqp::create(self)!SET-SELF(@parts.eager,$plus,$whatever,$string)
}

method !SLOW-NEW(str $s) {
Expand All @@ -30,6 +32,7 @@ class Version {
(my int $pos),
(my int $chars = nqp::chars($s)),
(my int $mark),
(my int $whatever = 0),
(my $strings := nqp::list_s),
(my $parts := nqp::list),
nqp::while(
Expand All @@ -39,6 +42,7 @@ class Version {
nqp::stmts( # Whatever portion
nqp::push_s($strings, '*'),
nqp::push($parts, * ),
($whatever = 1),
($pos = nqp::add_i($pos, 1))),
nqp::if(
nqp::iscclass(nqp::const::CCLASS_NUMERIC, $s, $pos),
Expand Down Expand Up @@ -77,23 +81,23 @@ class Version {
nqp::stmts(
(my int $plus = nqp::eqat($s, '+',
nqp::sub_i(nqp::chars($s), 1))),
nqp::create(self)!SET-SELF($parts, $plus,
nqp::create(self)!SET-SELF($parts, $plus, $whatever,
nqp::concat(nqp::join('.', $strings), $plus ?? '+' !! '')))))
}
# highlander cache
my $v6; my $v6c; my $vplus;
multi method new(Version: Str() $s) {
nqp::if(
nqp::iseq_s($s, '6'), # highlanderize most common
($v6 //= nqp::create(Version)!SET-SELF(nqp::list(6),0,"6")),
($v6 //= nqp::create(Version)!SET-SELF(nqp::list(6),0,0,"6")),
nqp::if(
nqp::iseq_s($s, '6.c'),
($v6c //= nqp::create(Version)!SET-SELF(nqp::list(6,"c"),0,"6.c")),
($v6c //= nqp::create(Version)!SET-SELF(nqp::list(6,"c"),0,0,"6.c")),
nqp::unless(
self!SLOW-NEW($s),
nqp::if(
nqp::eqat($s, '+', nqp::sub_i(nqp::chars($s),1)),
($vplus //= nqp::create(Version)!SET-SELF(nqp::list,1,"")),
($vplus //= nqp::create(Version)!SET-SELF(nqp::list,1,0,"")),
self.new))))
}

Expand Down Expand Up @@ -152,6 +156,7 @@ class Version {

method parts() { nqp::hllize($!parts) }
method plus() { nqp::hllbool($!plus) }
method whatever() { nqp::hllbool($!whatever) }
}


Expand Down
2 changes: 1 addition & 1 deletion tools/templates/main-version.in
Expand Up @@ -5,7 +5,7 @@ sub hll-config($config) {
$config<codename> := '@codename@';
$config<language-version> := '6.@lang_spec@';
# Though language-revisions key provides more information
# can-language-versions is kept for speeding up
# can-language-versions is used for speeding up and ordering
# Perl6::Compiler.can_langauge_versions method
$config<can-language-versions>
:= nqp::list( '6.c'@for_specmods(, '6.@spec_with_mod@')@ );
Expand Down

0 comments on commit e51d2ad

Please sign in to comment.