public static RakudoObject Bootstrap()
{
// Create our KnowHOW type object. Note we don't have a HOW
// just yet, so pass in null.
Representation REPR = REPRRegistry.get_REPR_by_name("KnowHOWREPR");
RakudoObject KnowHOW = REPR.type_object_for(null,null);
// We'll set up a dictionary of our various methods to go into
// KnowHOW's HOW, since we'll want to work with them a bit.
HashMap<String, RakudoObject> KnowHOWMeths = new HashMap<String, RakudoObject>();
KnowHOWMeths.put("new_type", CodeObjectUtility.WrapNativeMethod( new RakudoCodeRef.IFunc_Body() { // C# has a lambda
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
// We first create a new HOW instance.
RakudoObject knowHOWTypeObj = CaptureHelper.GetPositional(capture, 0);
RakudoObject HOW = knowHOWTypeObj.getSTable().REPR.instance_of(tc, knowHOWTypeObj.getSTable().WHAT);
// If we have a name arg, stash that value away.
RakudoObject typeName = CaptureHelper.GetNamed(capture, "name");
((KnowHOWREPR.KnowHOWInstance)HOW).Name = typeName != null ? typeName : Ops.box_str(tc, "<anon>");
// Now create a new type object to go with it of the
// desired REPR; we default to P6opaque (note that the
// KnowHOW repr only knows how to store a table of
// methods and attributes, it can't be used for an
// instance object that actually wants to store some
// instance data).
RakudoObject REPRName = CaptureHelper.GetNamed(capture, "repr");
if (REPRName != null)
{
// Look up the REPR.
Representation REPRToUse = REPRRegistry.get_REPR_by_name(Ops.unbox_str(null, REPRName));
return REPRToUse.type_object_for(null, HOW);
}
else
{
// Just go with the P6opaque REPR.
return REPRRegistry.get_REPR_by_name("P6opaque").type_object_for(tc, HOW);
}
}
}));
KnowHOWMeths.put("add_attribute", CodeObjectUtility.WrapNativeMethod( new RakudoCodeRef.IFunc_Body() { // an anonymous class where C# uses a lambda
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
KnowHOWREPR.KnowHOWInstance HOW = (KnowHOWREPR.KnowHOWInstance)CaptureHelper.GetPositional(capture, 0);
RakudoObject Attr = CaptureHelper.GetPositional(capture, 2);
HOW.Attributes.add(Attr);
return CaptureHelper.Nil();
}
}));
KnowHOWMeths.put("add_method", CodeObjectUtility.WrapNativeMethod( new RakudoCodeRef.IFunc_Body() { // an anonymous class where C# uses a lambda
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
KnowHOWREPR.KnowHOWInstance HOW = (KnowHOWREPR.KnowHOWInstance)CaptureHelper.GetPositional(capture, 0);
String name = CaptureHelper.GetPositionalAsString(capture, 2);
RakudoObject method = CaptureHelper.GetPositional(capture, 3);
HOW.Methods.put(name, method);
return CaptureHelper.Nil();
}
}));
KnowHOWMeths.put("find_method", CodeObjectUtility.WrapNativeMethod( new RakudoCodeRef.IFunc_Body() { // an anonymous class where C# uses a lambda
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
// We go to some effort to be really fast in here, 'cus it's a
// hot path for dynamic dispatches.
RakudoObject[] Positionals = ((P6capture.Instance)capture).Positionals;
assert Positionals.length >= 3;
KnowHOWREPR.KnowHOWInstance HOW = (KnowHOWREPR.KnowHOWInstance)Positionals[0];
if (HOW.Methods.containsKey(Ops.unbox_str(tc, Positionals[2])))
return HOW.Methods.get(Ops.unbox_str(tc, Positionals[2]));
else {
// throw new NoSuchMethodException("No such method " + Ops.unbox_str(tc, Positionals[1]));
throw new UnsupportedOperationException("No such method " + Ops.unbox_str(tc, Positionals[1]));
}
}
}));
KnowHOWMeths.put("compose", CodeObjectUtility.WrapNativeMethod( new RakudoCodeRef.IFunc_Body() { // an anonymous class where C# uses a lambda
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
RakudoObject obj = CaptureHelper.GetPositional(capture, 1);
return obj;
}
}));
KnowHOWMeths.put("attributes", CodeObjectUtility.WrapNativeMethod(new RakudoCodeRef.IFunc_Body() { // an anonymous class where C# uses a lambda
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
// Safe to just return a P6list instance that points at
// the same thing we hold internally, since a list is
// immutable. However, if default list type has no HOW,
// we will see if we can find one that does have it.
KnowHOWREPR.KnowHOWInstance HOW = (KnowHOWREPR.KnowHOWInstance)CaptureHelper.GetPositional(capture, 0);
RakudoObject listType = MostDefinedListType(tc);
RakudoObject result = listType.getSTable().REPR.instance_of(tc, listType);
((P6list.Instance)result).Storage = HOW.Attributes;
return result;
}
}));
KnowHOWMeths.put("methods", CodeObjectUtility.WrapNativeMethod(new RakudoCodeRef.IFunc_Body() { // an anonymous class where C# uses a lambda
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
// Return the methods list.
KnowHOWREPR.KnowHOWInstance HOW = (KnowHOWREPR.KnowHOWInstance)CaptureHelper.GetPositional(capture, 0);
RakudoObject listType = MostDefinedListType(tc);
RakudoObject result = listType.getSTable().REPR.instance_of(tc, listType);
((P6list.Instance)result).Storage.addAll(HOW.Methods.values());
return result;
}
}));
KnowHOWMeths.put("parents", CodeObjectUtility.WrapNativeMethod(new RakudoCodeRef.IFunc_Body() { // an anonymous class
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
// A pure prototype never has any parents, so return an empty list.
RakudoObject listType = MostDefinedListType(tc);
return listType.getSTable().REPR.instance_of(tc, listType);
}
}));
KnowHOWMeths.put("type_check", CodeObjectUtility.WrapNativeMethod(new RakudoCodeRef.IFunc_Body() { // an anonymous class
public RakudoObject Invoke(ThreadContext tc, RakudoObject ignored, RakudoObject capture)
{
// Can only match against ourselves.
RakudoObject self = CaptureHelper.GetPositional(capture, 1);
RakudoObject check = CaptureHelper.GetPositional(capture, 2);
return Ops.box_int(tc, self.getSTable().WHAT == check.getSTable().WHAT ? 1 : 0, tc.DefaultBoolBoxType);
}
}));
// We create a KnowHOW instance that can describe itself.
// This means .HOW.HOW.HOW.HOW etc will always return that,