Skip to content

Commit

Permalink
Merge pull request #30 from mjp41/0-fancy-locks
Browse files Browse the repository at this point in the history
Reify cowns and use builtins where possible
  • Loading branch information
xFrednet authored Oct 24, 2024
2 parents 27d6b32 + a6e0429 commit 15980fa
Show file tree
Hide file tree
Showing 23 changed files with 306 additions and 123 deletions.
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ clangformat_targets()


message(STATUS "Adding tests")
FILE(GLOB ALL_FILES
FILE(GLOB_RECURSE ALL_FILES
CONFIGURE_DEPENDS
tests/*
)
Expand All @@ -67,3 +67,6 @@ endforeach()

set_property(TEST three_regions.vpy PROPERTY WILL_FAIL true)
set_property(TEST leak_with_global.vpy PROPERTY WILL_FAIL true)
set_property(TEST invalid_read.vpy PROPERTY WILL_FAIL true)
set_property(TEST invalid_shared_region.vpy PROPERTY WILL_FAIL true)
set_property(TEST invalid_write.vpy PROPERTY WILL_FAIL true)
5 changes: 2 additions & 3 deletions src/lang/bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
/// The value name is stored in the location of the node
inline const trieste::TokenDef LoadFrame{"load_frame", trieste::flag::print};
inline const trieste::TokenDef StoreFrame{"store_frame", trieste::flag::print};
inline const trieste::TokenDef SwapFrame{"swap_frame", trieste::flag::print};
/// Loads a value with a given name from the current scope or the global
/// namespace. This should be used for function resolution.
///
/// The value name is stored in the location of the node
inline const trieste::TokenDef LoadGlobal{"load_global", trieste::flag::print};
inline const trieste::TokenDef LoadField{"load_field"};
inline const trieste::TokenDef StoreField{"store_field"};
inline const trieste::TokenDef SwapField{"swap_field"};
inline const trieste::TokenDef CreateObject{"create_object"};
inline const trieste::TokenDef Proto{"prototype"};
inline const trieste::TokenDef Dictionary{"dictionary"};
inline const trieste::TokenDef String{"string", trieste::flag::print};
inline const trieste::TokenDef KeyIter{"key_iter"};
Expand All @@ -33,8 +34,6 @@ inline const trieste::TokenDef ReturnValue{"return_value"};
/// Stack: `[]::<arg_0>` -> `[]::<arg_0>::<arg_0>`
inline const trieste::TokenDef Dup{"dup", trieste::flag::print};

inline const trieste::TokenDef CreateRegion{"create_region"};
inline const trieste::TokenDef FreezeObject{"freeze_object"};
inline const trieste::TokenDef Null{"null"};
inline const trieste::TokenDef Label{"label"};
inline const trieste::TokenDef Eq{"=="};
Expand Down
44 changes: 26 additions & 18 deletions src/lang/interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,6 @@ namespace verona::interpreter
obj = rt::make_iter(v);
rt::remove_reference(frame(), v);
}
else if (payload == Proto)
{
obj = rt::make_object();
// RC transferred
rt::set_prototype(obj, pop("prototype source"));
}
else if (payload == Func)
{
assert(
Expand Down Expand Up @@ -244,13 +238,26 @@ namespace verona::interpreter

if (node == StoreFrame)
{
assert(stack().size() >= 1 && "the stack is too small");
auto v = pop("value to store");
std::string field{node->location().view()};
auto v2 = rt::set(frame(), field, v);
rt::remove_reference(frame(), v2);
return ExecNext{};
}

if (node == SwapFrame)
{
assert(stack().size() >= 1 && "the stack is too small");
auto new_var = pop("swap value");
std::string field{node->location().view()};

auto old_var = rt::set(frame(), field, new_var);
stack().push_back(old_var);

return ExecNext{};
}

if (node == LoadField)
{
assert(stack().size() >= 2 && "the stack is too small");
Expand All @@ -275,6 +282,7 @@ namespace verona::interpreter

if (node == StoreField)
{
assert(stack().size() >= 3 && "the stack is too small");
auto v = pop("value to store");
auto k = pop("lookup-key");
auto v2 = pop("lookup-value");
Expand All @@ -286,19 +294,20 @@ namespace verona::interpreter
return ExecNext{};
}

if (node == CreateRegion)
if (node == SwapField)
{
auto v = pop("region source");
rt::create_region(v);
rt::remove_reference(frame(), v);
return ExecNext{};
}
assert(stack().size() >= 3 && "the stack is too small");
auto new_var = pop("swap value");
auto key = pop("lookup-key");
auto obj = pop("lookup-value");
auto old_var = rt::set(obj, key, new_var);
stack().push_back(old_var);

rt::move_reference(frame(), obj, new_var);
rt::move_reference(obj, frame(), old_var);
rt::remove_reference(frame(), obj);
rt::remove_reference(frame(), key);

if (node == FreezeObject)
{
auto v = pop("object to freeze");
rt::freeze(v);
rt::remove_reference(frame(), v);
return ExecNext{};
}

Expand Down Expand Up @@ -401,7 +410,6 @@ namespace verona::interpreter
if (result)
{
stack().push_back(result.value());
rt::add_reference(frame(), result.value());
}
rt::remove_reference(frame(), func);
return ExecNext{};
Expand Down
26 changes: 11 additions & 15 deletions src/lang/lang.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ using namespace trieste;

inline const TokenDef Ident{"ident", trieste::flag::print};
inline const TokenDef Assign{"assign"};
inline const TokenDef Create{"create"};
inline const TokenDef For{"for"};
inline const TokenDef If{"if"};
inline const TokenDef Else{"else"};
inline const TokenDef Block{"block"};
inline const TokenDef Empty{"empty"};
inline const TokenDef Drop{"drop"};
inline const TokenDef Freeze{"freeze"};
inline const TokenDef Region{"region"};
inline const TokenDef Take{"take"};
inline const TokenDef Lookup{"lookup"};
inline const TokenDef Parens{"parens"};
inline const TokenDef Method{"method"};
Expand All @@ -32,7 +30,7 @@ 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 | Call | Method | Take;
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 @@ -41,11 +39,9 @@ namespace verona::wf
inline const auto grouping = (Top <<= File) | (File <<= Body) |
(Body <<= Block) |
(Block <<=
(Freeze | Region | Assign | If | For | Func | Return | ReturnValue | Call |
Method)++) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) | (Region <<= Ident) |
(Freeze <<= Ident) | (Create <<= Ident) |
(Assign | If | For | Func | Return | ReturnValue | Call | Method)++) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) | (Take <<= (Lhs >>= lv)) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) |
(If <<= (Op >>= Cond) * Block * Block) |
(For <<= (Key >>= Ident) * (Value >>= Ident) * (Op >>= lv) * Block) |
(Eq <<= (Lhs >>= cmp_values) * (Rhs >>= cmp_values)) |
Expand All @@ -56,17 +52,17 @@ namespace verona::wf

inline const trieste::wf::Wellformed bytecode = (Top <<= Body) |
(Body <<=
(LoadFrame | LoadGlobal | StoreFrame | LoadField | StoreField | Drop |
Null | CreateObject | CreateRegion | FreezeObject | IterNext | Print |
Eq | Neq | Jump | JumpFalse | Label | Call | Return | ReturnValue |
ClearStack | Dup)++) |
(CreateObject <<= (Dictionary | String | KeyIter | Proto | Func)) |
(LoadFrame | LoadGlobal | StoreFrame | SwapFrame | LoadField | StoreField |
SwapField | Drop | Null | CreateObject | IterNext | Print | Eq | Neq |
Jump | JumpFalse | Label | Call | Return | ReturnValue | ClearStack |
Dup)++) |
(CreateObject <<= (Dictionary | String | KeyIter | Func)) |
(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, Call, Method, Take);
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
26 changes: 9 additions & 17 deletions src/lang/passes/bytecode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ PassDef bytecode()
<< create_from(LoadField, _(Lookup));
},

T(Compile) << (T(Take) << T(Ident)[Ident]) >>
[](auto& _) { return Seq << Null << create_from(SwapFrame, _(Ident)); },
T(Compile)
<< (T(Take) << (T(Lookup)[Lookup] << (Any[Op] * Any[Key] * End))) >>
[](auto& _) {
return Seq << (Compile << _[Op]) << (Compile << _[Key]) << Null
<< SwapField;
},

T(Compile) << (T(Assign)[Op] << (T(Ident)[Ident] * Any[Rhs])) >>
[](auto& _) {
return Seq << (Compile << _[Rhs]) << create_from(StoreFrame, _(Ident))
Expand All @@ -68,23 +77,6 @@ PassDef bytecode()
<< create_print(_(Assign));
},

T(Compile) << (T(Freeze)[Op] << T(Ident)[Ident]) >>
[](auto& _) {
return Seq << (Compile << _[Ident]) << FreezeObject
<< create_print(_(Op));
},

T(Compile) << (T(Create)[Op] << T(Ident)[Ident]) >>
[](auto& _) {
return Seq << (Compile << _[Ident]) << (CreateObject << Proto);
},

T(Compile) << (T(Region)[Op] << T(Ident)[Ident]) >>
[](auto& _) {
return Seq << (Compile << _[Ident]) << CreateRegion
<< create_print(_(Op));
},

T(Compile)
<< (T(Method)[Method]
<< ((T(Lookup)[Lookup] << (OPERAND[Op] * T(String)[Key])) *
Expand Down
4 changes: 2 additions & 2 deletions src/lang/passes/call_stmts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ namespace verona::wf

inline const auto call_stmts = grouping |
(Block <<=
(Freeze | Region | Assign | If | For | Func | Return | ReturnValue | Call |
Method | ClearStack | Print)++);
(Assign | If | For | Func | Return | ReturnValue | Call | Method |
ClearStack | Print)++);
}

PassDef call_stmts()
Expand Down
16 changes: 7 additions & 9 deletions src/lang/passes/flatten.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ namespace verona::wf
inline const trieste::wf::Wellformed flatten = (Top <<= File) |
(File <<= Body) |
(Body <<=
(Freeze | Region | Assign | Eq | Neq | Label | Jump | JumpFalse | Print |
StoreFrame | LoadFrame | CreateObject | Ident | IterNext | Create |
StoreField | Lookup | String | Call | Method | Return | ReturnValue |
ClearStack)++) |
(Assign | Take | Eq | Neq | Label | Jump | JumpFalse | Print | StoreFrame |
LoadFrame | CreateObject | Ident | IterNext | StoreField | Lookup |
String | Call | Method | Return | ReturnValue | ClearStack)++) |
(CreateObject <<= (KeyIter | String | Dictionary | Func)) |
(Func <<= Compile) | (Compile <<= Body) | (Create <<= Ident) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) | (Region <<= Ident) |
(Freeze <<= Ident) | (Call <<= Ident * List) | (Method <<= Lookup * List) |
(List <<= rv++) | (Params <<= Ident++) |
(Func <<= Compile) | (Compile <<= Body) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) | (Take <<= lv) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) | (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
25 changes: 5 additions & 20 deletions src/lang/passes/grouping.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,11 @@ 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(Drop)[Drop] << End) * LV[Lhs] * End) >>
[](auto& _) { return Assign << _(Lhs) << Null; },
T(Group) << ((T(Take)[Take] << End) * LV[Lhs] * End) >>
[](auto& _) { return create_from(Take, _(Take)) << _(Lhs); },

// function(arg, arg)
--In(Func) *
(T(Group)[Group] << (T(Ident)[Ident]) *
Expand Down Expand Up @@ -66,12 +57,6 @@ PassDef grouping()
return create_from(Method, _(Group)) << _(Lookup) << list;
},

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

T(Assign)
<< ((T(Group) << LV[Lhs] * End) *
((T(Group) << (RV[Rhs] * End)) / (RV[Rhs] * End)) * End) >>
Expand Down Expand Up @@ -123,10 +108,10 @@ PassDef grouping()
<< (Body << _(Block));
},
// Normalize parenthesis with a single node to also have a list token
T(Parens)[Parens] << (T(Group) << (Any[Ident] * End)) >>
T(Parens)[Parens] << ((T(Group) << (RV[Rhs] * End)) / (RV[Rhs] * End)) >>
[](auto& _) {
return create_from(Parens, _(Parens))
<< (create_from(List, _(Parens)) << _(Ident));
<< (create_from(List, _(Parens)) << _(Rhs));
},

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

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

Expand Down Expand Up @@ -157,9 +157,7 @@ trieste::Parse parser()
m.push(Block);
},
"drop\\b" >> [](auto& m) { m.add(Drop); },
"create\\b" >> [](auto& m) { m.add(Create); },
"freeze\\b" >> [](auto& m) { m.add(Freeze); },
"region\\b" >> [](auto& m) { m.add(Region); },
"take\\b" >> [](auto& m) { m.add(Take); },
"None\\b" >> [](auto& m) { m.add(Null); },
"[0-9A-Za-z_]+" >> [](auto& m) { m.add(Ident); },
"\\[" >> [](auto& m) { m.push(Lookup); },
Expand Down
Loading

0 comments on commit 15980fa

Please sign in to comment.