Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reify cowns and use builtins where possible #30

Merged
merged 5 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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