Skip to content

Commit

Permalink
Passes: Support cown creation
Browse files Browse the repository at this point in the history
  • Loading branch information
xFrednet committed Oct 19, 2024
1 parent 450dda4 commit b69a27f
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/lang/bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ inline const trieste::TokenDef StoreField{"store_field"};
inline const trieste::TokenDef CreateObject{"create_object"};
inline const trieste::TokenDef Proto{"prototype"};
inline const trieste::TokenDef Dictionary{"dictionary"};
inline const trieste::TokenDef Cown{"cown"};
inline const trieste::TokenDef String{"string", trieste::flag::print};
inline const trieste::TokenDef KeyIter{"key_iter"};
inline const trieste::TokenDef Func{"func"};
Expand Down
6 changes: 6 additions & 0 deletions src/lang/interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ namespace verona::interpreter
"CreateObject: A bytecode function requires a body node");
obj = rt::make_func(new Bytecode{payload->at(0)});
}
else if (payload == Cown)
{
auto v = pop("cown reagion");
obj = rt::make_cown(v);
rt::move_reference(frame(), obj, v);
}
else
{
assert(false && "CreateObject has to specify a value");
Expand Down
11 changes: 6 additions & 5 deletions src/lang/lang.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ inline const TokenDef Compile{"compile"};
namespace verona::wf
{
inline const auto lv = Ident | Lookup;
inline const auto rv = lv | Empty | Null | String | Create | Call | Method;
inline const auto rv =
lv | Empty | Null | String | Create | Call | Method | Cown;
inline const auto cmp_values = Ident | Lookup | Null;
inline const auto key = Ident | Lookup | String;
inline const auto operand = Lookup | Call | Method | Ident;
Expand All @@ -44,8 +45,8 @@ namespace verona::wf
ReturnValue | Call | Method)++) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) | (Region <<= Ident) |
(Freeze <<= Ident) | (Taint <<= Ident) | (Create <<= Ident) |
(If <<= Eq * Block * Block) |
(Freeze <<= Ident) | (Taint <<= Ident) | (Cown <<= Ident) |
(Create <<= Ident) | (If <<= Eq * Block * Block) |
(For <<= (Key >>= Ident) * (Value >>= Ident) * (Op >>= lv) * Block) |
(Eq <<= (Lhs >>= cmp_values) * (Rhs >>= cmp_values)) |
(Func <<= Ident * Params * Body) | (Call <<= Ident * List) |
Expand All @@ -58,13 +59,13 @@ namespace verona::wf
CreateObject | CreateRegion | FreezeObject | Taint | IterNext | Print |
Eq | Neq | Jump | JumpFalse | Label | Call | Return | ReturnValue |
ClearStack | Dup)++) |
(CreateObject <<= (Dictionary | String | KeyIter | Proto | Func)) |
(CreateObject <<= (Dictionary | String | KeyIter | Proto | Func | Cown)) |
(Func <<= Body) | (Label <<= Ident)[Ident];
}

inline const auto LV = T(Ident, Lookup);
inline const auto RV =
T(Empty, Ident, Lookup, Null, String, Create, Call, Method);
T(Empty, Ident, Lookup, Null, String, Create, Call, Method, Cown);
inline const auto CMP_V = T(Ident, Lookup, Null);
inline const auto KEY = T(Ident, Lookup, String);
inline const auto OPERAND = T(Lookup, Call, Method, Ident);
Expand Down
14 changes: 14 additions & 0 deletions src/lang/passes/bytecode.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "../lang.h"

inline const trieste::TokenDef DestructiveRead{"destructive_read"};

PassDef bytecode()
{
PassDef p{
Expand Down Expand Up @@ -79,6 +81,18 @@ PassDef bytecode()
return Seq << (Compile << _[Ident]) << create_from(Taint, _(Op));
},

T(Compile) << (T(DestructiveRead) << T(Ident)[Ident]) >>
[](auto& _) {
// Read the value from the frame and set the frame value to null
return Seq << (Compile << _(Ident)) << Null
<< create_from(StoreFrame, _(Ident));
},
T(Compile) << (T(Cown)[Op] << T(Ident)[Ident]) >>
[](auto& _) {
return Seq << (Compile << (DestructiveRead << _(Ident)))
<< (CreateObject << Cown);
},

T(Compile) << (T(Create)[Op] << T(Ident)[Ident]) >>
[](auto& _) {
return Seq << (Compile << _[Ident]) << (CreateObject << Proto);
Expand Down
5 changes: 3 additions & 2 deletions src/lang/passes/flatten.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ namespace verona::wf
(Func <<= Compile) | (Compile <<= Body) | (Create <<= Ident) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) | (Region <<= Ident) |
(Freeze <<= Ident) | (Taint <<= Ident) | (Call <<= Ident * List) |
(Method <<= Lookup * List) | (List <<= rv++) | (Params <<= Ident++) |
(Freeze <<= Ident) | (Taint <<= Ident) | (Cown <<= Ident) |
(Call <<= Ident * List) | (Method <<= Lookup * List) | (List <<= rv++) |
(Params <<= Ident++) |
(Eq <<= (Lhs >>= cmp_values) * (Rhs >>= cmp_values)) |
(Neq <<= (Lhs >>= cmp_values) * (Rhs >>= cmp_values)) |
(Label <<= Ident)[Ident];
Expand Down
20 changes: 5 additions & 15 deletions src/lang/passes/grouping.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,12 @@ PassDef grouping()
In(Group) * OPERAND[Op] * (T(Lookup)[Lookup] << (T(Group) << KEY[Rhs])) >>
[](auto& _) { return Lookup << _(Op) << _(Rhs); },

T(Group) << ((T(Region)[Region] << End) * T(Ident)[Ident] * End) >>
[](auto& _) {
_(Region)->extend(_(Ident)->location());
return _(Region) << _(Ident);
},

T(Group) << ((T(Freeze)[Freeze] << End) * T(Ident)[Ident] * End) >>
[](auto& _) {
_(Freeze)->extend(_(Ident)->location());
return _(Freeze) << _(Ident);
},

T(Group) << ((T(Taint)[Taint] << End) * T(Ident)[Ident] * End) >>
T(Group)
<< ((T(Freeze, Taint, Cown, Region)[Op] << End) * T(Ident)[Ident] *
End) >>
[](auto& _) {
_(Taint)->extend(_(Ident)->location());
return _(Taint) << _(Ident);
_(Op)->extend(_(Ident)->location());
return _(Op) << _(Ident);
},

T(Group) << ((T(Drop)[Drop] << End) * LV[Lhs] * End) >>
Expand Down
5 changes: 3 additions & 2 deletions src/lang/passes/parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace verona::wf
using namespace trieste::wf;

inline const auto parse_tokens = Region | Ident | Lookup | Empty | Freeze |
Drop | Taint | Null | String | Create | Parens;
Taint | Cown | Drop | Null | String | Create | Parens;
inline const auto parse_groups =
Group | Assign | If | Else | Block | For | Func | List | Return;

Expand Down Expand Up @@ -154,8 +154,9 @@ trieste::Parse parser()
"drop" >> [](auto& m) { m.add(Drop); },
"create" >> [](auto& m) { m.add(Create); },
"freeze" >> [](auto& m) { m.add(Freeze); },
"region" >> [](auto& m) { m.add(Region); },
"taint" >> [](auto& m) { m.add(Taint); },
"cown" >> [](auto& m) { m.add(Cown); },
"region" >> [](auto& m) { m.add(Region); },
"None" >> [](auto& m) { m.add(Null); },
"[0-9A-Za-z_]+" >> [](auto& m) { m.add(Ident); },
"\\[" >> [](auto& m) { m.push(Lookup); },
Expand Down
4 changes: 2 additions & 2 deletions src/rt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ namespace rt::core

public:
CownObject(objects::DynObject* region)
: objects::DynObject(cownPrototypeObject()),
: objects::DynObject(cownPrototypeObject())
{
// FIXME: Add once regions are reified
// assert(
Expand Down Expand Up @@ -218,7 +218,7 @@ namespace rt::core

bool is_cown() override
{
return false;
return true;
}
};

Expand Down
12 changes: 8 additions & 4 deletions src/rt/objects/dyn_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ namespace rt::objects
return;
}

assert(target->parent == src);
Region::dec_prc(target);
if (src)
{
assert(target->parent == src);
Region::dec_prc(target);
}
return;
}

Expand Down Expand Up @@ -234,7 +237,7 @@ namespace rt::objects
// TODO SCC algorithm
visit(this, [](Edge e) {
auto obj = e.target;
if (obj->is_immutable())
if (!obj || obj->is_immutable())
return false;

auto r = get_region(obj);
Expand All @@ -244,7 +247,8 @@ namespace rt::objects
}
obj->region.set_tag(ImmutableTag);

return !obj->is_cown();
auto cown = obj->is_cown();
return !cown;
});
}

Expand Down
21 changes: 21 additions & 0 deletions tests/valid_cowns.vpy
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
global = {}

# A simple cown
a = {}
a.b = {}
region a
c01 = cown a

# Store the cown in a global
global.cown = c01
taint global

# Freeze global with a cown
freeze global

# FIXME: traint with cowns is wrong
# FIXME: Show local region address
# FIXME: Cowns should have special rendering and out edges

drop c01
drop global

0 comments on commit b69a27f

Please sign in to comment.