Skip to content

Commit

Permalink
[mmd] Implement bindability checks
Browse files Browse the repository at this point in the history
  • Loading branch information
sorear committed Apr 6, 2011
1 parent 67836c1 commit f95532e
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 16 deletions.
2 changes: 1 addition & 1 deletion lib/Builtins.cs
Expand Up @@ -834,7 +834,7 @@ class CrossSource: ItemSource {
p = (Variable[]) o.slots[0];
n = o.slots[1] as VarHash;
}
nf = nf.info.Binder(nf, p, n);
nf = nf.info.Binder(nf, p, n, false);
nf.curDisp = de;
return nf;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Cursor.cs
Expand Up @@ -31,7 +31,7 @@ public sealed class GState {
}

Frame nf = m.info.Binder(Kernel.GetInferiorRoot()
.MakeChild(m.outer, m.info), pos, null);
.MakeChild(m.outer, m.info), pos, null, false);
nf.curDisp = m;
Kernel.RunInferior(nf);
}
Expand Down
32 changes: 24 additions & 8 deletions lib/Kernel.cs
Expand Up @@ -289,7 +289,8 @@ public class SubInfo {
private string PName(int rbase) {
return ((string)sig_r[rbase]) + " in " + name;
}
public unsafe Frame Binder(Frame th, Variable[] pos, VarHash named) {
public unsafe Frame Binder(Frame th, Variable[] pos, VarHash named,
bool quiet) {
th.pos = pos;
th.named = named;
// XXX I don't fully understand how this works, but it's
Expand Down Expand Up @@ -380,6 +381,7 @@ public class SubInfo {
src = Kernel.NewROScalar(type.typeObject);
goto gotit;
}
if (quiet) return null;
return Kernel.Die(th, "No value for parameter " + PName(rbase));
gotit:
if ((flags & SIG_F_RWTRANS) != 0) {
Expand All @@ -393,8 +395,10 @@ public class SubInfo {
//return Kernel.Die(th, "Binding " + PName(rbase) + ", cannot bind read-only value to is rw parameter");
// fast path
if (rw == src.rw && islist == src.islist) {
if (!src.type.HasMRO(type))
if (!src.type.HasMRO(type)) {
if (quiet) return null;
return Kernel.Die(th, "Nominal type check failed in binding" + PName(rbase) + "; got " + src.type.name + ", needed " + type.name);
}
if (src.whence != null)
Kernel.Vivify(src);
goto bound;
Expand All @@ -403,8 +407,10 @@ public class SubInfo {
// rw = false and islist = false and rhs.islist = true OR
// rw = false and islist = true and rhs.islist = false
P6any srco = src.Fetch();
if (!srco.mo.HasMRO(type))
if (!srco.mo.HasMRO(type)) {
if (quiet) return null;
return Kernel.Die(th, "Nominal type check failed in binding" + PName(rbase) + "; got " + srco.mo.name + ", needed " + type.name);
}
src = new SimpleVariable(false, islist, srco.mo, null, srco);
bound: ;
}
Expand All @@ -427,6 +433,7 @@ public class SubInfo {
noparams:

if (posc != pos.Length || namedc != null && namedc.Count != 0) {
if (quiet) return null;
string m = "Excess arguments to " + name;
if (posc != pos.Length)
m += string.Format(", used {0} of {1} positionals",
Expand Down Expand Up @@ -713,7 +720,7 @@ class InvokeSub : InvokeHandler {
SubInfo info = (SubInfo) dyo.slots[1];

Frame n = caller.MakeChild(outer, info);
n = n.info.Binder(n, pos, named);
n = n.info.Binder(n, pos, named, false);

return n;
}
Expand Down Expand Up @@ -1156,7 +1163,7 @@ public class Kernel {
P6opaque dyo = (P6opaque) sub;
Frame n = th.MakeChild((Frame) dyo.slots[0],
(SubInfo) dyo.slots[1]);
n = n.info.Binder(n, Variable.None, null);
n = n.info.Binder(n, Variable.None, null, false);
n.MarkSharedChain();
n.lex = new Dictionary<string,object>();
n.lex["!return"] = null;
Expand Down Expand Up @@ -1333,8 +1340,17 @@ public class MMDCandidateLongname {
while ((dth.info.param0 as P6any[]) == null) dth = dth.outer;

Console.WriteLine("---");
foreach (P6any p in dth.info.param0 as P6any[])
foreach (P6any p in dth.info.param0 as P6any[]) {
Console.WriteLine((new MMDCandidateLongname(p)).LongName());
SubInfo si = (SubInfo)p.GetSlot("info");
Frame o = (Frame)p.GetSlot("outer");
Frame nth = th.MakeChild(o, si);
if (nth.info.Binder(nth, dth.pos, dth.named, true) == null) {
Console.WriteLine("NOT BINDABLE");
} else {
Console.WriteLine("BINDABLE");
}
}

// XXX I think this is a harmless race
//MMDCandidate[] cs = dth.info.param1 as MMDCandidate[];
Expand Down Expand Up @@ -1869,7 +1885,7 @@ public class MMDCandidateLongname {
}
public static Frame InstantiateRole(Frame th, Variable[] pcl) {
Frame n = th.MakeChild(null, IRSI);
n = n.info.Binder(n, pcl, null);
n = n.info.Binder(n, pcl, null, false);
return n;
}

Expand Down Expand Up @@ -2322,7 +2338,7 @@ class LastFrameNode {
p = (Variable[]) o.slots[0];
n = o.slots[1] as VarHash;
}
tf = tf.info.Binder(tf, p, n);
tf = tf.info.Binder(tf, p, n, false);
tf.curDisp = de;
return tf;
} else {
Expand Down
2 changes: 1 addition & 1 deletion lib/ObjModel.cs
Expand Up @@ -33,7 +33,7 @@ public abstract class P6any {
//Kernel.LogNameLookup(name);
if (mo.mro_methods.TryGetValue(name, out m)) {
Frame nf = m.info.Binder(caller.MakeChild(m.outer, m.info),
pos, named);
pos, named, false);
nf.curDisp = m;
return nf;
}
Expand Down
8 changes: 3 additions & 5 deletions test2.pl
Expand Up @@ -86,7 +86,6 @@
is $log, "B", "bind called when needed (write)";
}

#`「
{
sub bar(Str $) {}
lives_ok { bar "foo" }, "can pass correct type";
Expand Down Expand Up @@ -118,13 +117,12 @@
is C20.b1("foo"), "str", "multimethods work (2)";

is C20.b2(True), "bool", "multimethod sorting works (1)";
is C20.b2("foo"), "any", "multimethod sorting works (1)";
is C20.b3(True), "bool", "multimethod sorting works (1)";
is C20.b3("foo"), "any", "multimethod sorting works (1)";
is C20.b2("foo"), "any", "multimethod sorting works (2)";
is C20.b3(True), "bool", "multimethod sorting works (3)";
is C20.b3("foo"), "any", "multimethod sorting works (4)";

dies_ok { C20.b4("foo", "bar") }, "multimethod tie checking works";
}

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

0 comments on commit f95532e

Please sign in to comment.