Skip to content

Commit

Permalink
Implement nextsame
Browse files Browse the repository at this point in the history
  • Loading branch information
sorear committed Oct 11, 2010
1 parent f65d43c commit c6bd89e
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
44 changes: 38 additions & 6 deletions lib/Kernel.cs
Expand Up @@ -175,15 +175,16 @@ public class SubInfo {
public const int ON_SUCCEED = 6;
public const int ON_PROCEED = 7;
public const int ON_GOTO = 8;
public const int ON_NEXTDISPATCH = 9;
public int[] edata;
public string[] label_names;

private static string[] controls = new string[] { "unknown", "next",
"last", "redo", "return", "die", "succeed", "proceed", "goto",
"nextsame/nextwith" };
public static string DescribeControl(int type, Frame tgt, int lid,
string name) {
string ty = (type == ON_RETURN) ? "return" :
(type == ON_REDO) ? "redo" :
(type == ON_LAST) ? "last" :
(type == ON_NEXT) ? "next" : "unknown control";
string ty = (type < controls.Length) ? controls[type] : "unknown";
if (lid >= 0) {
return ty + "(" + tgt.info.label_names[lid] + ", lexotic)";
} else if (name != null) {
Expand Down Expand Up @@ -1141,6 +1142,13 @@ class ExitRunloopException : Exception { }
int unip = 0;

for (csr = th; csr != null; csr = csr.caller) {
if (type == SubInfo.ON_NEXTDISPATCH) {
if (csr.curDisp != null) {
unf = csr;
break;
}
continue;
}
// for lexoticism
if (tgt != null && tgt != csr)
continue;
Expand Down Expand Up @@ -1169,7 +1177,7 @@ class ExitRunloopException : Exception { }
r.lex0 = mp;
return r;
} else {
return Unwind(th, unf, unip, payload);
return Unwind(th, type, unf, unip, payload);
}
}

Expand Down Expand Up @@ -1200,8 +1208,32 @@ class ExitRunloopException : Exception { }
}
}

public static Frame Unwind(Frame th, Frame tf, int tip, object td) {
public static Frame Unwind(Frame th, int type, Frame tf, int tip,
object td) {
// LEAVE handlers aren't implemented yet.
if (type == SubInfo.ON_NEXTDISPATCH) {
// These are a bit special because there isn't actually a
// catching frame.
DispatchEnt de = tf.curDisp.next;
DynObject o = td as DynObject;
if (de != null) {
Variable[] p = tf.pos;
Dictionary<string, Variable> n = tf.named;
tf = tf.caller.MakeChild(de.outer, de.info);
if (o != null) {
tf.pos = (Variable[]) o.slots[0];
tf.named = o.slots[1] as Dictionary<string,Variable>;
} else {
tf.pos = p;
tf.named = n;
}
tf.curDisp = de;
return tf;
} else {
tf.caller.resultSlot = Kernel.NewROScalar(Kernel.AnyP);
return tf.caller;
}
}
tf.ip = tip;
tf.resultSlot = td;
return tf;
Expand Down
21 changes: 21 additions & 0 deletions test2.pl
@@ -1,6 +1,27 @@
# vim: ft=perl6
use Test;

sub nextsame() {
Q:CgOp { (control 9 (null frame) (int -1) (null str) (null obj)) }
}
{
my class A {
method tom() { 12 }
method foo($x) { $x * $x }
method bar(:$x) { $x + $x }
}
my class B is A {
method tom() { nextsame; }
method foo($x) { nextsame; } #OK
method bar(:$x) { nextsame; } #OK
}
is B.tom(), 12, "nextsame functional";
is B.foo(5), 25, "nextsame functional w/ argument";
# TODO
# is B.bar(:x(7)), 14, "nextsame functional w/ named arg";
}

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

Expand Down

0 comments on commit c6bd89e

Please sign in to comment.