Skip to content

Commit

Permalink
Lang: Convert create, freeze, region into functions
Browse files Browse the repository at this point in the history
  • Loading branch information
xFrednet committed Oct 24, 2024
1 parent 5dead00 commit 23427f0
Show file tree
Hide file tree
Showing 18 changed files with 84 additions and 116 deletions.
4 changes: 0 additions & 4 deletions src/lang/bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ inline const trieste::TokenDef SwapFrame{"swap_frame", trieste::flag::print};
inline const trieste::TokenDef LoadGlobal{"load_global", trieste::flag::print};
inline const trieste::TokenDef LoadField{"load_field"};
inline const trieste::TokenDef StoreField{"store_field"};
/// Stack: `[]::<new>::<obj>::<key>` -> `[]::<old>`
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 @@ -36,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
22 changes: 0 additions & 22 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 @@ -317,22 +311,6 @@ namespace verona::interpreter
return ExecNext{};
}

if (node == CreateRegion)
{
auto v = pop("region source");
rt::create_region(v);
rt::remove_reference(frame(), v);
return ExecNext{};
}

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

if (node == Eq || node == Neq)
{
auto b = pop("Rhs");
Expand Down
22 changes: 8 additions & 14 deletions src/lang/lang.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +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 Take{"take"};
inline const TokenDef Freeze{"freeze"};
inline const TokenDef Region{"region"};
inline const TokenDef Lookup{"lookup"};
inline const TokenDef Parens{"parens"};
inline const TokenDef Method{"method"};
Expand All @@ -33,8 +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 | Take;
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 @@ -43,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 | If | For | Func | Return | ReturnValue | Call | Method)++) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) | (Take <<= (Lhs >>= lv)) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) | (Region <<= Ident) |
(Freeze <<= Ident) | (Create <<= Ident) |
(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 @@ -59,16 +53,16 @@ namespace verona::wf
inline const trieste::wf::Wellformed bytecode = (Top <<= Body) |
(Body <<=
(LoadFrame | LoadGlobal | StoreFrame | SwapFrame | LoadField | StoreField |
SwapField | Drop | Null | CreateObject | CreateRegion | FreezeObject |
IterNext | Print | Eq | Neq | Jump | JumpFalse | Label | Call | Return |
ReturnValue | ClearStack | Dup)++) |
(CreateObject <<= (Dictionary | String | KeyIter | Proto | Func)) |
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, Take);
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
17 changes: 0 additions & 17 deletions src/lang/passes/bytecode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,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
14 changes: 6 additions & 8 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 | Take | 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) |
(Func <<= Compile) | (Compile <<= Body) |
(Assign <<= (Lhs >>= lv) * (Rhs >>= rv)) | (Take <<= lv) |
(Lookup <<= (Op >>= operand) * (Rhs >>= key)) | (Region <<= Ident) |
(Freeze <<= Ident) | (Call <<= Ident * List) | (Method <<= Lookup * List) |
(List <<= rv++) | (Params <<= Ident++) |
(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
18 changes: 0 additions & 18 deletions src/lang/passes/grouping.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,6 @@ 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) >>
Expand Down Expand Up @@ -69,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
7 changes: 2 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 | Take | 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 @@ -158,9 +158,6 @@ trieste::Parse parser()
},
"drop\\b" >> [](auto& m) { m.add(Drop); },
"take\\b" >> [](auto& m) { m.add(Take); },
"create\\b" >> [](auto& m) { m.add(Create); },
"freeze\\b" >> [](auto& m) { m.add(Freeze); },
"region\\b" >> [](auto& m) { m.add(Region); },
"None\\b" >> [](auto& m) { m.add(Null); },
"[0-9A-Za-z_]+" >> [](auto& m) { m.add(Ident); },
"\\[" >> [](auto& m) { m.push(Lookup); },
Expand Down
7 changes: 4 additions & 3 deletions src/rt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,10 @@ namespace rt::core
// FIXME: Also check that the region has a LRC == 1, with 1
// being the reference passed into this constructor

assert(
region->change_rc(0) == 1 &&
"regions used for cown creation need to have an rc of 1");
if (region->change_rc(0) != 1)
{
ui::error("regions used for cown creation need to have an rc of 1");
}

// this->set would fail, since this is a cown
this->fields["region"] = region;
Expand Down
46 changes: 44 additions & 2 deletions src/rt/core/builtin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@

namespace rt::core
{
rt::objects::DynObject*
pop(std::vector<rt::objects::DynObject*>* stack, char const* data_info)
{
auto v = stack->back();
stack->pop_back();
std::cout << "pop " << v << " (" << data_info << ")" << std::endl;
return v;
}

void mermaid_builtins(ui::UI* ui)
{
if (!ui->is_mermaid())
Expand Down Expand Up @@ -55,18 +64,51 @@ namespace rt::core
add_builtin("cown", [](auto frame, auto stack, auto args) {
assert(args == 1);

auto region = stack->back();
auto region = pop(stack, "region for cown creation");
auto cown = make_cown(region);
move_reference(frame, cown, region);
stack->pop_back();

return cown;
});

add_builtin("create", [](auto frame, auto stack, auto args) {
assert(args == 1);

auto obj = make_object();
// RC transferred
rt::set_prototype(obj, pop(stack, "prototype source"));

return obj;
});
}

void action_builtins()
{
add_builtin("freeze", [](auto frame, auto stack, auto args) {
assert(args == 1);

auto value = pop(stack, "object to freeze");
freeze(value);
remove_reference(frame, value);

return std::nullopt;
});

add_builtin("region", [](auto frame, auto stack, auto args) {
assert(args == 1);

auto value = pop(stack, "region source");
create_region(value);
remove_reference(frame, value);

return std::nullopt;
});
}

void init_builtins(ui::UI* ui)
{
mermaid_builtins(ui);
ctor_builtins();
action_builtins();
}
}
4 changes: 2 additions & 2 deletions tests/cowns/invalid_read.vpy
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# A simple cown
a = {}
region a
co = cown(a)
region(a)
co = cown(take a)

# Reading the cown is forbidden
dummy = co.region
4 changes: 2 additions & 2 deletions tests/cowns/invalid_shared_region.vpy
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Creating a region
a = {}
region a
region(a)

# LRC = 2
r01 = a

# Error due to invalid RC
co = cown(a)
co = cown(take a)
4 changes: 2 additions & 2 deletions tests/cowns/invalid_write.vpy
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# A simple cown
a = {}
region a
co = cown(a)
region(a)
co = cown(take a)

# Modifying the cown is forbidden
co.other = {}
5 changes: 2 additions & 3 deletions tests/cowns/valid_01.vpy
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ global = {}
# A simple cown
a = {}
a.b = {}
region a
region(a)


c01 = cown(take a)
Expand All @@ -12,7 +12,6 @@ c01 = cown(take a)
global.cown = take c01

# Freeze global with a cown
freeze global
freeze(global)

drop c01
drop global
8 changes: 3 additions & 5 deletions tests/prototype.vpy
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ a = {}
b = {}
c = {}

b["f"] = a
drop a
b["f"] = take a

c = create b
drop b
c = create(take b)
c["g"] = c["f"]

drop c
drop c
4 changes: 2 additions & 2 deletions tests/recursive_list.vpy
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ def new_list():
list = new_list()

# Required to not leak memory
region list
region(list)

value = "x"

# Dyrona doesn't freeze shared objects automatically (yet)
proto = value["__proto__"]
freeze proto
freeze(proto)
drop proto

insert(list.head, {})
Expand Down
Loading

0 comments on commit 23427f0

Please sign in to comment.