Skip to content

Commit

Permalink
Move defined, WHAT, isa, does into the RI so non-DynObjects can be mo…
Browse files Browse the repository at this point in the history
…re first class
  • Loading branch information
sorear committed Aug 14, 2010
1 parent 0b4529f commit 2372b67
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 19 deletions.
7 changes: 6 additions & 1 deletion CodeGen.pm
Expand Up @@ -12,7 +12,12 @@ use 5.010;
# Beta will do this using reflection
my %typedata = (
IP6 =>
{ HOW => [c => 'IP6'] },
{ Isa => [m => 'Boolean'],
Does => [m => 'Boolean'],
GetTypeName => [m => 'String'],
GetTypeObject=> [m => 'IP6'],
IsDefined => [m => 'Boolean'],
HOW => [c => 'IP6'] },
DynObject =>
{ klass => [f => 'DynMetaObject'],
slots => [f => 'Dictionary<string,Object>'] },
Expand Down
46 changes: 43 additions & 3 deletions Kernel.cs
Expand Up @@ -24,6 +24,11 @@ public interface IP6 {
Frame GetAttribute(Frame caller, string name);
//public Frame WHERE(Frame caller);
Frame HOW(Frame caller);
string GetTypeName();
IP6 GetTypeObject();
bool IsDefined();
bool Isa(DynMetaObject super);
bool Does(DynMetaObject super);
// These exist as a concession to circularity - FETCH as a completely
// ordinary method could not work under the current calling convention.
Frame Fetch(Frame caller);
Expand Down Expand Up @@ -106,6 +111,16 @@ public class Frame: IP6 {
return c;
}

public string GetTypeName() { return "Frame"; }
public bool IsDefined() { return true; }
public IP6 GetTypeObject() { return Kernel.CallFrameMO.typeObject; }
public bool Isa(DynMetaObject sc) {
return Kernel.CallFrameMO.HasMRO(sc);
}
public bool Does(DynMetaObject sc) {
return Kernel.CallFrameMO.HasMRO(sc);
}

public Frame Invoke(Frame c, Variable[] p,
Dictionary<string, Variable> n) {
return Kernel.Die(c, "Tried to invoke a Frame");
Expand Down Expand Up @@ -349,6 +364,26 @@ public class DynObject: IP6 {
return caller;
}

public IP6 GetTypeObject() {
return klass.typeObject;
}

public bool IsDefined() {
return slots != null;
}

public string GetTypeName() {
return klass.name;
}

public bool Isa(DynMetaObject mo) {
return klass.HasMRO(mo);
}

public bool Does(DynMetaObject mo) {
return klass.HasMRO(mo);
}

public Frame Invoke(Frame c, Variable[] p,
Dictionary<string, Variable> n) {
if (klass.OnInvoke != null) {
Expand Down Expand Up @@ -381,9 +416,8 @@ public class DynObject: IP6 {
}
}

// Allows native CLR objects to be treated as Perl 6 data. They don't
// currently support any operations; you'll need to use CLR code to work
// with them.
// This class is slated for bloody death. See Kernel.BoxAny for the
// replacement.
public class CLRImportObject : IP6 {
public readonly object val;

Expand Down Expand Up @@ -417,6 +451,12 @@ public class CLRImportObject : IP6 {
//TODO
return Kernel.Die(c, "No metaobject available for CLRImportObject");
}

public IP6 GetTypeObject() { return null; }
public bool IsDefined() { return true; }
public string GetTypeName() { return "<clr>"; }
public bool Isa(DynMetaObject mo) { return false; }
public bool Does(DynMetaObject mo) { return false; }
}

// A bunch of stuff which raises big circularity issues if done in the
Expand Down
3 changes: 1 addition & 2 deletions Op.pm
Expand Up @@ -245,8 +245,7 @@ use CgOp;
$c = CgOp::how($c);
}
when ("WHAT") {
$c = CgOp::getfield('typeObject',
CgOp::getfield('klass', CgOp::cast('DynObject', $c)));
$c = CgOp::rawcall(CgOp::cast('IP6', $c), 'GetTypeObject');
}
default {
die "Invalid interrogative $_";
Expand Down
17 changes: 4 additions & 13 deletions SAFE.setting
Expand Up @@ -350,15 +350,11 @@ sub infix:<~~>($t,$m) { ($m.defined) ?? ($m.ACCEPTS($t)) !! ($t.^does($m)) }
PRE-INIT {
# rawcall to avoid putting a rw binding on self... TODO
Mu.HOW.add-method("defined", anon method defined is rawcall {
Q:CgOp { (box Bool (!= (null Dictionary<string,object>)
(getfield slots (cast DynObject (@ (pos 0)))))) }
Q:CgOp { (box Bool (rawcall (@ (pos 0)) IsDefined)) }
});
Mu.HOW.add-method("Bool", anon method Bool() { self.defined });
Mu.HOW.add-method("Str", anon method Str() {
my $tn := Q:CgOp {
(box Str (getfield name (getfield klass
(cast DynObject (fetch (scopedlex self))))))
};
my $tn := Q:CgOp { (box Str (rawcall (@ (l self)) GetTypeName)) };
if self.defined {
$tn ~ "()<instance>"
} else {
Expand Down Expand Up @@ -404,8 +400,8 @@ PRE-INIT {
Sub.HOW.add-method("ACCEPTS", anon method ACCEPTS($t) { (self)($t) });
ClassHOW.HOW.add-method("isa", anon method isa($obj, $type) { Q:CgOp {
(box Bool (rawcall (getfield klass (cast DynObject (@ (l $obj))))
HasMRO (getfield klass (cast DynObject (@ (l $type))))))
(box Bool (rawcall (@ (l $obj)) Isa
(getfield klass (cast DynObject (@ (l $type))))))
} });
ClassHOW.HOW.add-method("does",
anon method does($obj, $role) { self.isa($obj, $role) }); #no roles yet
Expand Down Expand Up @@ -704,11 +700,6 @@ PRE-INIT {
}
my class CallFrame {
# major fudge until Mu starts treating the RI with respect
method Bool { True }
method defined { True }
method Str { "callframe" }
method caller() { Q:CgOp {
(letn c (getfield caller (cast Frame (@ (l self))))
(ternary
Expand Down

0 comments on commit 2372b67

Please sign in to comment.