Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement 'is copy'
  • Loading branch information
sorear committed May 27, 2011
1 parent 673862f commit 5967651
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/CLRBackend.cs
Expand Up @@ -3996,6 +3996,7 @@ class NamProcessor {
if ((flags & 512) != 0) ufl |= SubInfo.SIG_F_DEFOUTER;
if ((flags & 1024) != 0) ufl |= SubInfo.SIG_F_INVOCANT;
if ((flags & 2048) != 0) ufl |= SubInfo.SIG_F_MULTI_IGNORED;
if ((flags & 4096) != 0) ufl |= SubInfo.SIG_F_IS_COPY;
if (deflt != null) {
ufl |= SubInfo.SIG_F_HASDEFAULT;
sig_r.Add(deflt);
Expand All @@ -4004,6 +4005,8 @@ class NamProcessor {
ufl |= SubInfo.SIG_F_HASTYPE;
sig_r.Add(type);
}
if ((flags & 128) != 0) ufl |= SubInfo.SIG_F_IS_LIST;
if ((flags & 256) != 0) ufl |= SubInfo.SIG_F_IS_HASH;
if ((flags & 16) != 0) ufl |= SubInfo.SIG_F_OPTIONAL;
if ((flags & 32) != 0) ufl |= SubInfo.SIG_F_POSITIONAL;
if ((flags & 1) != 0 && (flags & 256) != 0)
Expand Down
17 changes: 17 additions & 0 deletions lib/Kernel.cs
Expand Up @@ -666,6 +666,9 @@ public class SubInfo {
public const int SIG_F_RWTRANS = 8;
public const int SIG_F_BINDLIST = 16;
public const int SIG_F_INVOCANT = 8192;
public const int SIG_F_IS_COPY = 32768;
public const int SIG_F_IS_LIST = 65536;
public const int SIG_F_IS_HASH = 131072;

// Value source
public const int SIG_F_HASDEFAULT = 32;
Expand Down Expand Up @@ -830,6 +833,20 @@ public class SubInfo {
return Kernel.Die(th, "No value for parameter " + PName(rbase));
gotit:
if ((flags & SIG_F_RWTRANS) != 0) {
} else if ((flags & SIG_F_IS_COPY) != 0) {
Variable nvar;
if ((flags & SIG_F_IS_HASH) != 0)
nvar = Kernel.CreateHash();
else if ((flags & SIG_F_IS_LIST) != 0)
nvar = Kernel.CreateArray();
else
nvar = Kernel.NewTypedScalar(type);

if (nvar.islist)
Kernel.RunInferior(Kernel.Assign(Kernel.GetInferiorRoot(), nvar, src));
else
nvar.Store(src.Fetch());
src = nvar;
} else {
bool islist = ((flags & SIG_F_BINDLIST) != 0);
bool rw = ((flags & SIG_F_READWRITE) != 0) && !islist;
Expand Down
2 changes: 2 additions & 0 deletions src/NAMOutput.pm6
Expand Up @@ -293,6 +293,7 @@ augment class Sig::Parameter { #OK exist
$flags = $flags +| 512 if $.defouter;
$flags = $flags +| 1024 if $.invocant;
$flags = $flags +| 2048 if $.multi_ignored;
$flags = $flags +| 4096 if $.is_copy;

[
$.name,
Expand All @@ -314,6 +315,7 @@ sub parm_from_nam(@block) {
rw => ?($flags +& 64), list => ?($flags +& 128),
hash => ?($flags +& 256), defouter => ?($flags +& 512),
invocant => ?($flags +& 1024), multi_ignored => ?($flags +& 2048),
is_copy => ?($flags +& 4096),
name => $name, slot => $slot, names => $names, :$tclass);
}

Expand Down
78 changes: 78 additions & 0 deletions src/niecza
Expand Up @@ -30,7 +30,85 @@ use Sig;

# Operator::Method.meta, Op::CallMethod.ismeta now Str

augment class Sig::Parameter { #OK
method bind_inline($body, @posr) {
my $get = $!full_parcel ?? self.parcel_get_inline(@posr) !!
$!slurpycap ?? self.slurpycap_get_inline(@posr) !!
$!slurpy ?? self.slurpy_get_inline(@posr) !!
self.single_get_inline($body, @posr);

if (defined $!slot) {
if $!is_copy {
self.do_copy($get);
} else {
CgOp.scopedlex($!slot, $!rwtrans ?? $get !!
CgOp.newboundvar(+(!$!rw), +$!list, $get));
}
} else {
CgOp.sink($get);
}
}
}

augment class NieczaActions {
method simple_longname($/) {
my $r = self.mangle_longname($/);
($r<path>:exists) ?? [ @($r<path>), $r<name> ] !! [ 'MY', $r<name> ];
}

method parameter($/) {
my $rw = False;
my $copy = False;
my $sorry;
my $slurpy = False;
my $slurpycap = False;
my $optional = False;
my $rwt = False;
my $type;

if $<type_constraint> {
$type = self.simple_longname($<type_constraint>[0]<typename><longname>);
}

for @( $<trait> ) -> $trait {
if $trait.ast<rw> { $rw = True }
elsif $trait.ast<copy> { $copy = True }
elsif $trait.ast<parcel> { $rwt = True }
elsif $trait.ast<readonly> { $rw = False }
else {
$trait.CURSOR.sorry('Unhandled trait ' ~ $trait.ast.keys.[0]);
}
}

if $<post_constraint> > 0 {
$/.sorry('Parameter post constraints NYI');
make ::Sig::Parameter.new;
return Nil;
}

my $default = $<default_value> ?? $<default_value>[0].ast !! Any;

my $tag = $<quant> ~ ':' ~ $<kind>;
if $tag eq '**:*' { $sorry = "Slice parameters NYI" }
elsif $tag eq '*:*' { $slurpy = True }
elsif $tag eq '|:*' { $slurpycap = True }
elsif $tag eq '\\:!' { $rwt = True }
elsif $tag eq '\\:?' { $rwt = True; $optional = True }
elsif $tag eq ':!' { }
elsif $tag eq ':*' { $optional = True }
elsif $tag eq ':?' { $optional = True }
elsif $tag eq '?:?' { $optional = True }
elsif $tag eq '!:!' { }
elsif $tag eq '!:?' { $optional = True }
elsif $tag eq '!:*' { }
else { $sorry = "Confusing parameters ($tag)" }
if $sorry { $/.CURSOR.sorry($sorry); }
my $p = $<param_var> // $<named_param>;

make ::Sig::Parameter.new(name => ~$/, :$default,
:$optional, :$slurpy, :$rw, type => ($type // 'Any'),
:$slurpycap, rwtrans => $rwt, is_copy => $copy, |$p.ast);
}
}

augment class CgOp {
Expand Down
8 changes: 8 additions & 0 deletions test2.pl
Expand Up @@ -67,6 +67,14 @@
is $st, '5Bool::False', 'repeat until (postfix) can take ->';
}

{
sub foo($x is copy) { $x++; $x }
is foo(5), 6, "is copy works (non inline)";
my $y;
for 5 -> $k is copy { $k++; $y = $k }
is $y, 6, "is copy works (inline)";
}

#is $?FILE, 'test.pl', '$?FILE works';
#is $?ORIG.substr(0,5), '# vim', '$?ORIG works';

Expand Down

0 comments on commit 5967651

Please sign in to comment.