Skip to content
Browse files

Implement $foo.::($bar)() form

  • Loading branch information...
1 parent 881f22b commit 59f5ccbaa66901b3f8fee1391a887a278a28a8ce @sorear committed
Showing with 62 additions and 3 deletions.
  1. +31 −0 lib/Builtins.cs
  2. +1 −1 src/CgOp.pm6
  3. +5 −0 src/Op.pm6
  4. +2 −2 src/Operator.pm6
  5. +23 −0 src/niecza
View
31 lib/Builtins.cs
@@ -2821,4 +2821,35 @@ public class Blackhole : Variable {
}
public static int ref_hash(P6any o) { return RuntimeHelpers.GetHashCode(o); }
+
+ public static Frame ind_method_call(Frame th, StashCursor root,
+ string nm, P6any cap) {
+ int cut = nm.LastIndexOf("::");
+ var pos = (Variable[]) cap.GetSlot(Kernel.CaptureMO, "$!positionals");
+ var nam = (VarHash) cap.GetSlot(Kernel.CaptureMO, "$!named");
+
+ if (cut < 0) {
+ return pos[0].Fetch().InvokeMethod(th, nm, pos, nam);
+ } else {
+ var from = root.Indirect(nm.Substring(0, cut), false, null)
+ .Fetch().mo;
+ var name = nm.Substring(cut+2);
+
+ // some code copied from dispatch_fromtype
+ if (!pos[0].Fetch().Does(from)) {
+ return Kernel.Die(th, "Cannot dispatch to a method on " +
+ from.name + " because it is not inherited or done by " +
+ pos[0].Fetch().mo.name);
+ }
+
+ var de = from.FindMethod(name);
+ if (de != null) {
+ return de.info.SetupCall(th, de.outer, de.ip6,
+ pos, nam, false, de);
+ } else {
+ return Kernel.Die(th, "Unable to resolve method " + name +
+ " via " + from.name);
+ }
+ }
+ }
}
View
2 src/CgOp.pm6
@@ -66,7 +66,7 @@ CgOp._register_ops: <
vvarlist_new_empty vvarlist_new_singleton vvarlist_pop
vvarlist_push vvarlist_shift vvarlist_sort vvarlist_to_fvarlist
vvarlist_unshift vvarlist_unshiftn whileloop xspan times
- divop obj_can sqrt push pop unshift shift
+ divop obj_can sqrt push pop unshift shift ind_method_call
newarray newhash you_are_here frame_outer frame_sub makejunction
who sc_root sc_indir temporize _addmethod _invalidate rxlprim >;
View
5 src/Op.pm6
@@ -202,6 +202,11 @@ class CallMethod is CallLike {
$CgOp.fetch($r))), "can", $r, $CgOp.box('Str',$n))),
$CgOp.methodcall($r, $n, self.argblock($body)),
$CgOp.scopedlex('Nil'))})});
+ } elsif $meta eq '::(' {
+ $CgOp.ind_method_call($CgOp.sc_root(), $name,
+ $CgOp.fetch($CgOp.subcall($CgOp.fetch(
+ $CgOp.corelex('&_make_capture')),
+ $!receiver.cgop($body), self.argblock($body))));
} elsif $!pclass {
$CgOp.methodcall($.receiver.cgop($body), 'dispatch:<::>',
$CgOp.class_ref('typeVar', $!pclass), $CgOp.box("Str",$name),
View
4 src/Operator.pm6
@@ -97,8 +97,8 @@ class PostCall is Operator {
class Method is Operator {
has $.name; # Str | Op; .foo; use args, meta, private, path
has $.args = [];
- has $.meta; # Bool
- has $.private; # Bool
+ has Str $.meta;
+ has Bool $.private; # Bool
has $.package; # Xref
method clone(*%_) {
View
23 src/niecza
@@ -49,6 +49,29 @@ our ($RxOp, $RxOpAlt, $RxOpAny, $RxOpBefore, $RxOpCut, $RxOpConj, $RxOpCutLTM,
our ($Sig, $SigParameter, $PassSimplifier, $CClass); #OK
our $Actions; $Actions = $Actions but role {
+method methodop($/) {
+ if $<longname> {
+ my ($c) = self.process_name($<longname>, :defer);
+ make $Operator_Method.new(name => 'die');
+ unless $c {
+ $/.CURSOR.sorry("Method call requires a name");
+ return;
+ }
+ if $c<iname> {
+ make $Operator_Method.new(name => $c<iname>, meta => '::(');
+ return;
+ }
+ make $Operator_Method.new(name => $c<name>, package => $c<pkg>);
+ } elsif $<quote> {
+ make $Operator_Method.new(name => $<quote>.ast);
+ } elsif $<variable> {
+ make $Operator_Function.new(function =>
+ self.do_variable_reference($/, $<variable>.ast));
+ }
+
+ $/.ast.args = $<args>.ast[0] // [] if $<args>;
+ $/.ast.args = $<arglist>.ast if $<arglist>;
+}
method FALLBACK($meth, $/) {
my $S = $<sym>;

0 comments on commit 59f5ccb

Please sign in to comment.
Something went wrong with that request. Please try again.