Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement @.foo and %.foo attributes
  • Loading branch information
sorear committed May 26, 2011
1 parent 44f9c45 commit dd9d259
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 27 deletions.
2 changes: 0 additions & 2 deletions TODO
Expand Up @@ -35,8 +35,6 @@ MEDIUM

+ $obj.?method

+ has @!foo; (needs to ignore types for now)

+ &hyperunary

+ for-loops with multiple parameters
Expand Down
20 changes: 14 additions & 6 deletions lib/CLRBackend.cs
Expand Up @@ -797,17 +797,19 @@ class Method {

class Attribute {
public readonly string name;
public readonly char sigil;
public readonly bool publ;
public readonly string ivar;
public readonly Xref ibody;
public readonly Xref type;

public Attribute(object[] x) {
name = JScalar.S(x[0]);
publ = JScalar.B(x[1]);
ivar = JScalar.S(x[2]);
ibody = Xref.from(x[3]);
type = Xref.from(x[4]);
sigil = JScalar.S(x[1])[0];
publ = JScalar.B(x[2]);
ivar = JScalar.S(x[3]);
ibody = Xref.from(x[4]);
type = Xref.from(x[5]);
}

public static Attribute[] fromArray(object x) {
Expand Down Expand Up @@ -4154,8 +4156,11 @@ class NamProcessor {
}

foreach (Attribute a in pr.attributes) {
int flags = a.publ ? 1 : 0;
if (a.sigil == '@') flags += 2;
if (a.sigil == '%') flags += 4;
CpsOp name = CpsOp.StringLiteral(a.name);
CpsOp publ = CpsOp.BoolLiteral(a.publ);
CpsOp publ = CpsOp.IntLiteral(flags);
CpsOp init = a.ivar == null ? CpsOp.Null(Tokens.P6any) :
RawAccessLex("scopedlex", a.ivar, null);
CpsOp type = a.type == null ?
Expand Down Expand Up @@ -4400,8 +4405,11 @@ public class CLRBackend {
}
unit.EmitInt(attrs.Length);
foreach (Attribute a in attrs) {
int flags = a.publ ? 1 : 0;
if (a.sigil == '@') flags += 2;
if (a.sigil == '%') flags += 4;
unit.EmitStr(a.name);
unit.EmitByte(a.publ ? 1 : 0);
unit.EmitByte((byte)flags);
unit.EmitXref(a.ibody);
unit.EmitXref(a.type);
}
Expand Down
32 changes: 21 additions & 11 deletions lib/Kernel.cs
Expand Up @@ -562,10 +562,10 @@ public sealed class RuntimeUnit {

for (int i = 0; i < nattr; i++) {
string name = ReadStr(ref from);
bool pub = heap[from++] != 0;
int flags = heap[from++];
SubInfo init = ReadXref(ref from) as SubInfo;
STable type = ReadXref(ref from) as STable;
into.AddAttribute(name, pub,
into.AddAttribute(name, flags,
init != null ? init.protosub : null,
type != null ? type : Kernel.AnyMO);
}
Expand Down Expand Up @@ -2369,17 +2369,27 @@ public class MMDCandidateLongname {

for (int i = mro.Length - 1; i >= 0; i--) {
foreach (P6how.AttrInfo a in mro[i].mo.local_attr) {
P6any val;
Variable vx;
if (a.publ && args.TryGetValue(a.name, out vx)) {
val = vx.Fetch();
} else if (a.init == null) {
val = a.type.typeObject;
Variable vx = null;
int kind = a.flags & (P6how.A_ARRAY | P6how.A_HASH);
if ((a.flags & P6how.A_PUBLIC) != 0 &&
args.TryGetValue(a.name, out vx)) {
} else if (a.init != null) {
vx = RunInferior(a.init.Invoke(GetInferiorRoot(),
Variable.None, null));
} else if (kind == 0) {
vx = a.type.typeVar;
} else {
val = RunInferior(a.init.Invoke(GetInferiorRoot(),
Variable.None, null)).Fetch();
vx = null;
}
if (kind == 0) {
n.SetSlot(a.name, NewRWScalar(a.type, vx.Fetch()));
} else {
Variable obj = (kind == P6how.A_HASH) ? CreateHash() :
CreateArray();
if (vx != null)
RunInferior(Assign(GetInferiorRoot(), obj, vx));
n.SetSlot(a.name, obj);
}
n.SetSlot(a.name, NewRWScalar(a.type, val));
}
}

Expand Down
14 changes: 9 additions & 5 deletions lib/ObjModel.cs
Expand Up @@ -129,10 +129,14 @@ public class P6how {
public struct AttrInfo {
public string name;
public P6any init;
public bool publ;
public int flags;
public STable type;
}

public const int A_PUBLIC = 1;
public const int A_ARRAY = 2;
public const int A_HASH = 4;

// 0 must be public only
public const int V_PUBLIC = 0;
public const int V_PRIVATE = 1;
Expand Down Expand Up @@ -352,11 +356,11 @@ public class DispatchSet {
lmethods.Add(mi);
}

public void AddAttribute(string name, bool publ, P6any init,
public void AddAttribute(string name, int flags, P6any init,
STable type) {
AttrInfo ai;
ai.name = name;
ai.publ = publ;
ai.flags = flags;
ai.init = init;
ai.type = type;
local_attr.Add(ai);
Expand Down Expand Up @@ -578,9 +582,9 @@ public class STable {
mo.AddMethod(flags, name, code);
}

public void AddAttribute(string name, bool publ, P6any init,
public void AddAttribute(string name, int flags, P6any init,
STable type) {
mo.AddAttribute(name, publ, init, type);
mo.AddAttribute(name, flags, init, type);
}

public void FillProtoClass(string[] slots) {
Expand Down
6 changes: 3 additions & 3 deletions src/NAMOutput.pm6
Expand Up @@ -261,7 +261,7 @@ augment class Metamodel::Method { #OK exist

augment class Metamodel::Attribute { #OK exist
method to_nam() {
[ $.name, $.public, $.ivar, $.ibody, $.typeconstraint ]
[ $.name, $.sigil, $.public, $.ivar, $.ibody, $.typeconstraint ]
}
}

Expand All @@ -273,8 +273,8 @@ sub method_from_nam(@block) {
}

sub attr_from_nam(@block) {
my ($name, $public, $ivar, $ibody, $typeconstraint) = @block;
::Metamodel::Attribute.new(:$name, :$public, :$ivar, :$ibody,
my ($name, $sigil, $public, $ivar, $ibody, $typeconstraint) = @block;
::Metamodel::Attribute.new(:$name, :$public, :$ivar, :$ibody, :$sigil,
:$typeconstraint);
}

Expand Down
13 changes: 13 additions & 0 deletions test2.pl
Expand Up @@ -2,6 +2,19 @@
use Test;
use MONKEY_TYPING;

{
my class Foo {
has @.bar;
has %.baz;
has @.quux = 1,2,3;
}
isa_ok Foo.new.bar, Array, '@.bar initializes as an array';
isa_ok Foo.new.baz, Hash, '%.baz initializes as a hash';
is +[ Foo.new(bar => (1,2,4)).bar ], 3, '@.bar initializes with list context';
is +[ Foo.new(bar => 5).bar ], 1, '@.bar can initialize from a single item';
is +[ Foo.new.quux ], 3, '@.quux with init list works';
}

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

Expand Down

0 comments on commit dd9d259

Please sign in to comment.