Skip to content

Commit

Permalink
Method: Simple methods with self are working
Browse files Browse the repository at this point in the history
  • Loading branch information
xFrednet committed Oct 17, 2024
1 parent 7a9d2b3 commit 06b61aa
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 8 deletions.
7 changes: 7 additions & 0 deletions src/lang/bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ inline const trieste::TokenDef Body{"body", trieste::flag::symtab};
inline const trieste::TokenDef Return{"return"};
inline const trieste::TokenDef ReturnValue{"return_value"};

/// Duplicates an item on the stack. The location of the
/// note is an index from the end of the stack, that indicates
/// which value should be duplicate.
///
/// Stack: `[]::<arg_0>` -> `[]::<arg_0>::<arg_0>`
inline const trieste::TokenDef Copy{"copy", trieste::flag::print};

inline const trieste::TokenDef CreateRegion{"create_region"};
inline const trieste::TokenDef FreezeObject{"freeze_object"};
inline const trieste::TokenDef Null{"null"};
Expand Down
16 changes: 16 additions & 0 deletions src/lang/interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,22 @@ namespace verona::interpreter
return action;
}

if (node == Copy)
{
// This breaks the normal idea of a stack machine, but every other
// solution would require more effort and would be messier
auto copy_idx = std::stoul(std::string(node->location().view()));
auto stack_size = stack().size();
assert(copy_idx < stack_size && "the stack is too small for this copy");

auto var = stack()[stack_size - copy_idx - 1];
stack().push_back(var);
std::cout << "push " << var << std::endl;
rt::add_reference(frame(), var);

return ExecNext{};
}

if (node == Return)
{
return ExecReturn{};
Expand Down
16 changes: 11 additions & 5 deletions src/lang/lang.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ 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"};

inline const TokenDef Op{"op"};
inline const TokenDef Rhs{"rhs"};
Expand All @@ -31,9 +32,10 @@ inline const TokenDef Compile{"compile"};
namespace verona::wf
{
inline const auto lv = Ident | Lookup;
inline const auto rv = lv | Empty | Null | String | Create | Call;
inline const auto rv = lv | Empty | Null | String | Create | Call | Method;
inline const auto cmp_values = Ident | Lookup | Null;
inline const auto key = Ident | Lookup | String;
inline const auto operand = Lookup | Call | Method | Ident;

inline const auto grouping = (Top <<= File) | (File <<= Body) |
(Body <<= Block) |
Expand All @@ -45,22 +47,26 @@ namespace verona::wf
(Freeze <<= 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 <<= (Op >>= key) * List) |
(ReturnValue <<= rv) | (List <<= rv++) | (Params <<= Ident++);
(Func <<= Ident * Params * Body) | (Call <<= Ident * List) |
(Method <<= Lookup * List) | (ReturnValue <<= rv) | (List <<= rv++) |
(Params <<= Ident++);

inline const trieste::wf::Wellformed bytecode = (Top <<= Body) |
(Body <<=
(LoadFrame | StoreFrame | LoadField | StoreField | Drop | Null |
CreateObject | CreateRegion | FreezeObject | IterNext | Print | Eq | Neq |
Jump | JumpFalse | Label | Call | Return | ReturnValue | ClearStack)++) |
Jump | JumpFalse | Label | Call | Return | ReturnValue | ClearStack |
Copy)++) |
(CreateObject <<= (Dictionary | String | KeyIter | Proto | 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);
inline const auto RV =
T(Empty, Ident, Lookup, Null, String, Create, Call, Method);
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);

// Parsing && AST construction
Parse parser();
Expand Down
18 changes: 18 additions & 0 deletions src/lang/passes/bytecode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ PassDef bytecode()
<< create_print(_(Op));
},

T(Compile)
<< (T(Method)[Method]
<< ((T(Lookup)[Lookup] << (OPERAND[Op] * T(String)[Key])) *
(T(List) << Any++[List]) * End)) >>
[](auto& _) {
auto arg_ctn = _[List].size();
return Seq
// `self` lookup and first argument
<< (Compile << _(Op))
<< (Compile << _[List])
// Copy self
<< (Copy ^ std::to_string(arg_ctn))
// Fetch the function
<< (Compile << _(Key))
<< create_from(LoadField, _(Lookup))
// function call, +1 for the self argument
<< (Call ^ std::to_string(arg_ctn + 1));
},
T(Compile)
<< (T(Call)[Call] << (KEY[Op] * (T(List) << Any++[List]) * End)) >>
[](auto& _) {
Expand Down
4 changes: 2 additions & 2 deletions src/lang/passes/flatten.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ namespace verona::wf
(Body <<=
(Freeze | Region | Assign | Eq | Neq | Label | Jump | JumpFalse | Print |
StoreFrame | LoadFrame | CreateObject | Ident | IterNext | Create |
StoreField | Lookup | String | Call | Return | ReturnValue |
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 <<= (Lhs >>= lv) * (Rhs >>= key)) | (Region <<= Ident) |
(Freeze <<= Ident) | (Call <<= (Op >>= key) * List) | (List <<= rv++) |
(Freeze <<= 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)) |
Expand Down
23 changes: 22 additions & 1 deletion src/lang/passes/grouping.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ PassDef grouping()

return create_from(Call, _(Group)) << _(Ident) << list;
},
--In(Method) *
(T(Group)[Group]
<< ((T(Lookup)[Lookup]) * (T(Parens)[Parens] << (~T(List)[List])) *
End)) >>
[](auto& _) {
auto list = _(List);
if (!list)
{
list = create_from(List, _(Parens));
}

return create_from(Method, _(Group)) << _(Lookup) << list;
},

T(Group) << ((T(Create)[Create] << End) * T(Ident)[Ident] * End) >>
[](auto& _) {
Expand Down Expand Up @@ -89,14 +102,22 @@ PassDef grouping()
<< ((T(Group) << End) *
(T(Group)
<< ((T(Ident)[Ident]) *
(T(Parens)[Parens] << (~(T(List) << T(Ident)++[List]))) *
(T(Parens)[Parens] << (
// (T(Group) << T(Ident)[List]) /
~(T(List) << T(Ident)++[List]))) *
End)) *
(T(Group) << T(Block)[Block]) * End) >>
[](auto& _) {
return create_from(Func, _(Func))
<< _(Ident) << (create_from(Params, _(Parens)) << _[List])
<< (Body << _(Block));
},
// Normalize functions with a single ident to also have a list token
T(Parens)[Parens] << (T(Group) << (T(Ident)[Ident] * End)) >>
[](auto& _) {
return create_from(Parens, _(Parens))
<< (create_from(List, _(Parens)) << _(Ident));
},

T(Return)[Return] << ((T(Group) << End) * End) >>
[](auto& _) { return create_from(Return, _(Return)); },
Expand Down
11 changes: 11 additions & 0 deletions tests/self.vpy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

def str_name(self):
return "String"

value = "Music :3"
value.name = str_name
drop str_name

name = value.name()


0 comments on commit 06b61aa

Please sign in to comment.