Skip to content

Commit

Permalink
Make subset behave depending on what language revision created it
Browse files Browse the repository at this point in the history
For the purpose of supporting language version dependent functionality a
new metamodel role is being introduced:
`Perl6::Metamodel::LanguageRevision`. It is in turn consumes
`Perl6::Metamodel::Versioning`.

SubsetHOW records the compiler version which created a subset type
object and then later checks against the version in order to determine
if old or new behaviour is expected.
  • Loading branch information
vrurg committed Aug 16, 2019
1 parent 15d9c93 commit 199c409
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 8 deletions.
3 changes: 0 additions & 3 deletions src/Perl6/Actions.nqp
Expand Up @@ -3567,11 +3567,9 @@ class Perl6::Actions is HLL::Actions does STDActions {
sub check_default_value_type($/, $descriptor, $bind_constraint, $what) {
my $matches;
my $maybe := 0;
note("TRY check_default_value_type") if nqp::getenvhash<RAKUDO_DEBUG>;
try {
$matches := nqp::istype($descriptor.default, $bind_constraint);
CATCH {
note("IN CATCH") if nqp::getenvhash<RAKUDO_DEBUG>;
$maybe := 1;
my $pl := nqp::getpayload($_);
if nqp::istype($pl, $*W.find_symbol(['Exception'])) {
Expand All @@ -3583,7 +3581,6 @@ class Perl6::Actions is HLL::Actions does STDActions {
}
}
unless $matches {
note("NO MATCH $maybe") if nqp::getenvhash<RAKUDO_DEBUG>;
$/.typed_sorry('X::Syntax::Variable::MissingInitializer',
type => nqp::how($bind_constraint).name($bind_constraint),
:$maybe,
Expand Down
20 changes: 20 additions & 0 deletions src/Perl6/Metamodel/LanguageRevision.nqp
@@ -0,0 +1,20 @@
# This role is for metaclasses with languare-revision dependent behavior.
role Perl6::Metamodel::LanguageRevision
does Perl6::Metamodel::Versioning
{
has $!lang_rev;

# The only allowed version format is 6.X
method set_language_version($obj, $ver) {
(nqp::iseq_i(nqp::chars($ver), 3) && nqp::eqat($ver, '6.', 0))
|| nqp::die("Language version must be a string in '6.<rev>' format, got `$ver`.");
self.set_ver($obj, $ver);
$!lang_rev := nqp::substr($ver, 2, 1);
}

method lang-rev-before($rev) {
nqp::iseq_i(nqp::chars($rev), 1)
|| nqp::die("Language revision must be a single letter, got `$rev`.");
nqp::iseq_i(nqp::cmp_s($!lang_rev, $rev), -1)
}
}
10 changes: 9 additions & 1 deletion src/Perl6/Metamodel/SubsetHOW.nqp
Expand Up @@ -2,6 +2,7 @@ class Perl6::Metamodel::SubsetHOW
does Perl6::Metamodel::Naming
does Perl6::Metamodel::Documenting
does Perl6::Metamodel::Stashing
does Perl6::Metamodel::LanguageRevision
{
# The subset type or nominal type that we refine.
has $!refinee;
Expand All @@ -27,6 +28,9 @@ class Perl6::Metamodel::SubsetHOW
my $metasubset := self.new(:refinee($refinee), :refinement($refinement));
my $type := nqp::settypehll(nqp::newtype($metasubset, 'Uninstantiable'), 'perl6');
$metasubset.set_name($type, $name);
# TODO This only works at compile time. To support run-time creation of subsets we need to find caller's CORE.
# Will be possible when nqp::p6callerrevision() is implemented.
$metasubset.set_language_version($metasubset, nqp::getcomp('perl6').language_version);
nqp::settypecheckmode($type, 2);
self.add_stash($type)
}
Expand Down Expand Up @@ -77,7 +81,11 @@ class Perl6::Metamodel::SubsetHOW

# Do check when we're on LHS of smartmatch (e.g. Even ~~ Int).
method type_check($obj, $checkee) {
nqp::hllboolfor( nqp::istype($!refinee, $checkee), "perl6" )
nqp::hllboolfor(
(self.lang-rev-before('e') && nqp::istrue($checkee.HOW =:= self))
|| nqp::istype($!refinee, $checkee),
"perl6"
)
}

# Here we check the value itself (when on RHS on smartmatch).
Expand Down
8 changes: 4 additions & 4 deletions src/Perl6/World.nqp
Expand Up @@ -2037,15 +2037,15 @@ class Perl6::World is HLL::World {
method maybe-definite-how-base($v) {
# returns the value itself, unless it's a DefiniteHOW, in which case,
# it returns its base type. Behaviour available in 6.d and later only.
! $*W.lang-ver-before('d') && nqp::eqaddr($v.HOW,
! $*W.lang-ver-before('d') && nqp::eqaddr($v.HOW,
$*W.find_symbol: ['Metamodel','DefiniteHOW'], :setting-only
) ?? $v.HOW.base_type: $v !! $v
}

method maybe-nominalize($v) {
# if $*W.lang-ver-before('e') {
# return self.maybe-definite-how-base($v);
# }
if $*W.lang-ver-before('e') {
return self.maybe-definite-how-base($v);
}
$v.HOW.archetypes.nominalizable ?? $v.HOW.nominalize($v) !! $v
}

Expand Down
1 change: 1 addition & 0 deletions tools/templates/common_bootstrap_sources
Expand Up @@ -4,6 +4,7 @@ src/Perl6/Metamodel/Naming.nqp
src/Perl6/Metamodel/Documenting.nqp
src/Perl6/Metamodel/Stashing.nqp
src/Perl6/Metamodel/Versioning.nqp
src/Perl6/Metamodel/LanguageRevision.nqp
src/Perl6/Metamodel/TypePretense.nqp
src/Perl6/Metamodel/MethodDelegation.nqp
src/Perl6/Metamodel/BoolificationProtocol.nqp
Expand Down

0 comments on commit 199c409

Please sign in to comment.