Skip to content

Commit

Permalink
Switch to a more composable model of method types
Browse files Browse the repository at this point in the history
  • Loading branch information
sorear committed Mar 15, 2011
1 parent 543ebb3 commit 1954503
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 65 deletions.
4 changes: 0 additions & 4 deletions TODO
Expand Up @@ -23,8 +23,6 @@ EASY

Rename at-key, at-pos to "postcircumfix:<[ ]>" etc.

Implement $obj.$( code )

Add your favorite missing function to the setting, with tests.
In particular, I could use: sprintf, dir, write, close, split, ...

Expand All @@ -47,8 +45,6 @@ EASY
Stuff spectests are blocking on: "Block", "&hash", "writable $_",
"closure for", "ranges of chars", "gather for",

At least parsing Int et al on my-decls would help a lot

MEDIUM

+ qx[]
Expand Down
30 changes: 12 additions & 18 deletions lib/CLRBackend.cs
Expand Up @@ -389,7 +389,7 @@ class ModuleWithTypeObject: Module {
class Method {
public readonly string name;
public readonly object cname;
public readonly string kind;
public readonly int kind;
public readonly string var;
public readonly Xref body;

Expand All @@ -399,7 +399,7 @@ class Method {
} else {
cname = x[0];
}
kind = JScalar.S(x[1]);
kind = JScalar.I(x[1]);
var = JScalar.S(x[2]);
body = Xref.from(x[3]);
}
Expand Down Expand Up @@ -976,16 +976,8 @@ sealed class Tokens {
typeof(Builtins).GetMethod("MEMap");
public static readonly MethodInfo Builtins_MEGrep =
typeof(Builtins).GetMethod("MEGrep");
public static readonly Dictionary<string,MethodInfo> DMO_AddFooMethod
= _FooMethod();
private static Dictionary<string,MethodInfo> _FooMethod() {
Dictionary<string,MethodInfo> n =
new Dictionary<string,MethodInfo>();
n["normal"] = STable.GetMethod("AddMethod");
n["private"] = STable.GetMethod("AddPrivateMethod");
n["sub"] = STable.GetMethod("AddSubMethod");
return n;
}
public static readonly MethodInfo DMO_AddMethod =
typeof(STable).GetMethod("AddMethod");
public static readonly MethodInfo DMO_AddAttribute =
typeof(STable).GetMethod("AddAttribute");
public static readonly MethodInfo DMO_Invalidate =
Expand Down Expand Up @@ -3126,7 +3118,7 @@ class NamProcessor {
thandlers["path_modified"] = Methody(null, typeof(Builtins).GetMethod("GetModTime"));
handlers["_parametricrole"] = delegate(NamProcessor th, object[] z) { return th.FillParamRole(); };
handlers["_addmethod"] = delegate(NamProcessor th, object[] z) {
return CpsOp.MethodCall(null, Tokens.DMO_AddFooMethod[JScalar.S(z[1])], new CpsOp[] { th.Scan(z[2]), th.Scan(z[3]), th.Scan(z[4]) }); };
return CpsOp.MethodCall(null, Tokens.DMO_AddMethod, new CpsOp[] { th.Scan(z[1]), CpsOp.IntLiteral(JScalar.I(z[2])), th.Scan(z[3]), th.Scan(z[4]) }); };
thandlers["_invalidate"] = Methody(null, Tokens.STable.GetMethod("Invalidate"));
handlers["do_require"] = delegate(NamProcessor th, object[] z) {
return CpsOp.MethodCall(null, Tokens.Kernel.GetMethod("DoRequire"),
Expand Down Expand Up @@ -3449,9 +3441,9 @@ class NamProcessor {
CpsOp name = (m.name != null) ? CpsOp.StringLiteral(m.name) :
Scan(new object[] { new JScalar("obj_getstr"), m.cname });
CpsOp var = RawAccessLex("scopedlex", m.var, null);
MethodInfo a = Tokens.DMO_AddFooMethod[m.kind];

build.Add(CpsOp.MethodCall(null, a, new CpsOp[] { mo, name,
build.Add(CpsOp.MethodCall(null, Tokens.DMO_AddMethod,
new CpsOp[] { mo, CpsOp.IntLiteral(m.kind), name,
CpsOp.MethodCall(null, Tokens.Variable_Fetch, new CpsOp[] { var }) }));
}

Expand Down Expand Up @@ -3516,10 +3508,12 @@ class NamProcessor {
object[] tuples = (object[]) sub.augment_hack;
for (int i = 1; i < tuples.Length; i++) {
object[] t = (object[]) tuples[i];
string k = JScalar.S(t[0]);
int ik = (k == "normal") ? 0 : (k == "private") ? 1 : 2;
enter.Add(new object[] {
new JScalar( "_addmethod" ),
t[0],
new object[] { new JScalar("letvar"), new JScalar("!mo") },
new JScalar(ik.ToString()),
new object[] { new JScalar("str"), t[1] },
new object[] { new JScalar("fetch"), new object[] { new JScalar("scopedlex"), t[2] } } });
}
Expand Down Expand Up @@ -3808,9 +3802,9 @@ public class CLRBackend {
Attribute[] attrs = (m is Class) ? ((Class)m).attributes :
((Role)m).attributes;
foreach (Method me in methods) {
MethodInfo mi = Tokens.DMO_AddFooMethod[me.kind];
thaw.Add(CpsOp.MethodCall(null, mi, new CpsOp[] {
thaw.Add(CpsOp.MethodCall(null, Tokens.DMO_AddMethod, new CpsOp[] {
CpsOp.GetSField(m.metaObject),
CpsOp.IntLiteral(me.kind),
CpsOp.StringLiteral(me.name),
CpsOp.GetSField(me.body.Resolve<StaticSub>().protosub)
}));
Expand Down
15 changes: 10 additions & 5 deletions lib/Cursor.cs
Expand Up @@ -1404,7 +1404,10 @@ public class LexerCache {
if (mo.superclasses.Count == 1) {
parent = mo.superclasses[0].GetLexerCache();
repl_methods = new HashSet<string>();
foreach (string mn in mo.local.Keys) {
foreach (STable.MethodInfo mi in mo.lmethods) {
if ((mi.flags & STable.V_MASK) != STable.V_PUBLIC)
continue;
string mn = mi.short_name;
int ix = mn.IndexOf(':');
if (ix >= 0) repl_methods.Add(mn.Substring(0,ix));
else repl_methods.Add(mn);
Expand Down Expand Up @@ -1675,11 +1678,13 @@ public class Lexer {
foreach (STable k in cursor_class.mro) {
if (proto != k.Can(name))
continue;
foreach (KeyValuePair<string,P6any> o in k.ord_methods) {
if (!Utils.StartsWithInvariant(filter, o.Key))
foreach (STable.MethodInfo o in k.lmethods) {
if ((o.flags & STable.V_MASK) != STable.V_PUBLIC)
continue;
if (!Utils.StartsWithInvariant(filter, o.short_name))
continue;
if (cursor_class.Can(o.Key) == o.Value) {
raword.Add((P6opaque) o.Value);
if (cursor_class.Can(o.short_name) == o.impl) {
raword.Add((P6opaque) o.impl);
}
}
}
Expand Down
93 changes: 58 additions & 35 deletions lib/Kernel.cs
Expand Up @@ -1140,6 +1140,30 @@ public struct AttrInfo {
public STable type;
}

// 0 must be public only
public const int V_PUBLIC = 0;
public const int V_PRIVATE = 1;
public const int V_SUBMETHOD = 2;
public const int V_MASK = 3;

public const int M_ONLY = 0;
public const int M_PROTO = 4;
public const int M_MULTI = 8;
public const int M_MASK = 12;

public struct MethodInfo {
public string short_name;
public string long_name;

public string Name() {
return ((flags & STable.M_MASK) != 0) ? long_name : short_name;
}

public P6any impl;

public int flags;
}

public static readonly ContextHandler<Variable> CallStr
= new CtxCallMethod("Str");
public static readonly ContextHandler<Variable> CallBool
Expand Down Expand Up @@ -1216,19 +1240,13 @@ public struct AttrInfo {
public InvokeHandler mro_INVOKE;

public Dictionary<string, DispatchEnt> mro_methods;
public Dictionary<string, P6any> private_mro;

public STable[] local_does;

public List<STable> superclasses
= new List<STable>();
public Dictionary<string, P6any> local
= new Dictionary<string, P6any>();
public List<KeyValuePair<string, P6any>> ord_methods
= new List<KeyValuePair<string, P6any>>();
public Dictionary<string, P6any> priv
= new Dictionary<string, P6any>();
public Dictionary<string, P6any> submethods
= new Dictionary<string, P6any>();
public List<MethodInfo> lmethods = new List<MethodInfo>();
public List<AttrInfo> local_attr = new List<AttrInfo>();

public Dictionary<string, int> slotMap = new Dictionary<string, int>();
Expand All @@ -1255,6 +1273,7 @@ public List<STable> superclasses

private void Revalidate() {
mro_methods = new Dictionary<string,DispatchEnt>();
private_mro = new Dictionary<string,P6any>();

if (mro == null)
return;
Expand All @@ -1263,17 +1282,26 @@ public List<STable> superclasses

for (int kx = mro.Length - 1; kx >= 0; kx--) {
STable k = mro[kx];
foreach (KeyValuePair<string,P6any> m in k.ord_methods) {
foreach (MethodInfo m in k.lmethods) {
DispatchEnt de;
mro_methods.TryGetValue(m.Key, out de);
mro_methods[m.Key] = new DispatchEnt(de, m.Value);
if ((m.flags & V_MASK) != V_PUBLIC)
continue;
string n = m.Name();
mro_methods.TryGetValue(n, out de);
mro_methods[n] = new DispatchEnt(de, m.impl);
}
}

foreach (KeyValuePair<string,P6any> m in submethods) {
DispatchEnt de;
mro_methods.TryGetValue(m.Key, out de);
mro_methods[m.Key] = new DispatchEnt(de, m.Value);
foreach (MethodInfo m in lmethods) {
string n = m.Name();
if ((m.flags & V_MASK) == V_PRIVATE) {
private_mro[n] = m.impl;
}
else if ((m.flags & V_MASK) == V_SUBMETHOD) {
DispatchEnt de;
mro_methods.TryGetValue(n, out de);
mro_methods[n] = new DispatchEnt(de, m.impl);
}
}

mro_at_key = _GetVT("at-key") as IndexHandler ?? CallAtKey;
Expand Down Expand Up @@ -1361,17 +1389,14 @@ public List<STable> superclasses
}
}

public void AddMethod(string name, P6any code) {
local[name] = code;
ord_methods.Add(new KeyValuePair<string,P6any>(name, code));
}

public void AddPrivateMethod(string name, P6any code) {
priv[name] = code;
}

public void AddSubMethod(string name, P6any code) {
submethods[name] = code;
public void AddMethod(int flags, string name, P6any code) {
MethodInfo mi;
//SubInfo si = (SubInfo) code.GetSlot("info");
mi.impl = code;
mi.short_name = name;
mi.long_name = name; // TODO: signature encoding
mi.flags = flags;
lmethods.Add(mi);
}

public void AddAttribute(string name, bool publ, P6any init,
Expand All @@ -1385,7 +1410,7 @@ public List<STable> superclasses
}

public P6any GetPrivateMethod(string name) {
P6any code = priv[name];
P6any code = private_mro[name];
if (code == null) { throw new NieczaException("private method lookup failed for " + name + " in class " + this.name); }
return code;
}
Expand Down Expand Up @@ -2051,7 +2076,7 @@ public class Kernel {
si.sig_r = new object[1] { "self" };
si.vtable_boxed = cvb;
si.vtable_unboxed = cvu;
kl.AddMethod(name, MakeSub(si, null));
kl.AddMethod(0, name, MakeSub(si, null));
}

private static void WrapHandler1(STable kl, string name,
Expand All @@ -2068,7 +2093,7 @@ public class Kernel {
};
si.sig_r = new object[2] { "self", "$key" };
si.vtable_boxed = cv;
kl.AddMethod(name, MakeSub(si, null));
kl.AddMethod(0, name, MakeSub(si, null));
}

private static SubInfo IRSI = new SubInfo("InstantiateRole", IRC);
Expand Down Expand Up @@ -2142,12 +2167,10 @@ public class Kernel {
Array.Copy(b.mro, 0, nmro, 1, b.mro.Length);
nmro[0] = n;
n.FillClass(b.all_slot, new STable[] { b }, nmro);
foreach (KeyValuePair<string, P6any> kv in role.priv)
n.AddPrivateMethod(kv.Key, kv.Value);
foreach (STable.MethodInfo mi in role.lmethods)
n.lmethods.Add(mi);
foreach (STable.AttrInfo ai in role.local_attr)
n.AddAttribute(ai.name, ai.publ, ai.init, ai.type);
foreach (KeyValuePair<string, P6any> kv in role.ord_methods)
n.AddMethod(kv.Key, kv.Value);
n.local_attr.Add(ai);
n.Invalidate();

n.how = BoxAny<STable>(n, b.how).Fetch();
Expand Down Expand Up @@ -2338,7 +2361,7 @@ class LastFrameNode {
SubMO = new STable("Sub");
SubInvokeSubSI.vtable_boxed = new InvokeSub();
SubMO.FillProtoClass(new string[] { "outer", "info" });
SubMO.AddMethod("INVOKE", MakeSub(SubInvokeSubSI, null));
SubMO.AddMethod(0, "INVOKE", MakeSub(SubInvokeSubSI, null));
SubMO.Invalidate();

LabelMO = new STable("Label");
Expand Down
2 changes: 1 addition & 1 deletion lib/NieczaCLR.cs
Expand Up @@ -128,7 +128,7 @@ public class NieczaCLR {

if (NieczaCLROpts.Debug)
Console.WriteLine("Installing {0}", siname);
m.AddMethod(n, Kernel.MakeSub(new SubInfo(siname, method), null));
m.AddMethod(0,n, Kernel.MakeSub(new SubInfo(siname, method), null));
}

m.Invalidate();
Expand Down
7 changes: 5 additions & 2 deletions src/NAMOutput.pm6
Expand Up @@ -234,9 +234,11 @@ augment class Metamodel::ParametricRole { #OK exist
}
}

my %methodtypes = ( normal => 0, private => 1, sub => 2 );
my @methodfromtype = ('normal', 'private', 'sub');
augment class Metamodel::Method { #OK exist
method to_nam() {
[ $.name, $.kind, $.var, $.body ]
[ $.name, %methodtypes{$.kind}, $.var, $.body ]
}
}

Expand All @@ -248,7 +250,8 @@ augment class Metamodel::Attribute { #OK exist

sub method_from_nam(@block) {
my ($name, $kind, $var, $body) = @block;
::Metamodel::Method.new(:$name, :$kind, :$var, :$body);
::Metamodel::Method.new(:$name, kind => @methodfromtype[$kind], :$var,
:$body);
}

sub attr_from_nam(@block) {
Expand Down

0 comments on commit 1954503

Please sign in to comment.