Commit c307f373 authored by Tom Niget's avatar Tom Niget

Work on mutexes (wip)

parent e2d96f04
......@@ -12,8 +12,10 @@
#include <string>
#include <python/basedef.hpp>
#include <typon/typon.hpp>
#ifdef __cpp_lib_unreachable
#include <utility>
[[noreturn]] inline void TYPON_UNREACHABLE() { std::unreachable(); }
......@@ -62,14 +64,13 @@ template <PySmartPtr T> struct RealType<T> {
namespace typon {
//class TyNone {};
// class TyNone {};
using TyNone = std::nullopt_t;
auto None = std::nullopt;
} // namespace typon
static constexpr auto None = typon::None;
// typon_len
......@@ -127,7 +128,6 @@ std::ostream &operator<<(std::ostream &os, std::optional<T> const &opt) {
return opt ? os << opt.value() : os << "None";
}
#define system_error(err, message) \
do { \
puts(message); \
......@@ -140,12 +140,12 @@ std::ostream &operator<<(std::ostream &os, std::optional<T> const &opt) {
#include "builtins/dict.hpp"
#include "builtins/int.hpp"
#include "builtins/list.hpp"
#include "builtins/mutex.hpp"
#include "builtins/print.hpp"
#include "builtins/range.hpp"
#include "builtins/set.hpp"
#include "builtins/slice.hpp"
#include "builtins/str.hpp"
#include "builtins/mutex.hpp"
auto is_cpp() { return typon::TyBool(true); }
......@@ -421,8 +421,22 @@ template <auto IDX, typename T> auto constant_get(T &&val) {
}
}
struct {
using has_sync = std::true_type;
template <typename T>
auto typon$$sync(T value) const -> decltype(referencemodel::Rc(future(std::declval<Task<T>>())))
{
//return referencemodel::Rc(future(task));
throw;
}
template <typename Task>
auto operator()(Task task) const -> typon::Task<decltype(referencemodel::Rc(future(std::move(task))))>
{
co_return referencemodel::Rc(co_await future(std::move(task)));
}
} static constexpr future_stdlib{};
}; // namespace typon
......
......@@ -7,59 +7,62 @@
namespace view = std::views;
#include <python/basedef.hpp>
#include "print.hpp"
namespace typon {
using namespace referencemodel;
template<typename _Base0 = object>
template <typename _Base0 = object>
struct TyCell__oo : classtype<_Base0, TyCell__oo<>> {
static constexpr std::string_view name = "Cell";
static constexpr std::string_view name = "Cell";
template<typename T>
struct Obj : instance<TyCell__oo<>, Obj<T>> {
T val;
template <typename T> struct Obj : instance<TyCell__oo<>, Obj<T>> {
T val;
Obj() = default;
Obj(Obj const&) = delete;
};
Obj() = default;
Obj(Obj const &) = delete;
};
template<typename T>
auto operator()(T val) const {
return Obj<T>{val};
}
template <typename T> auto operator()(T val) const { return Obj<T>{val}; }
};
template<typename _Base0 = object>
template <typename _Base0 = object>
struct TyMutex__oo : classtype<_Base0, TyMutex__oo<>> {
static constexpr std::string_view name = "Mutex";
template<typename T>
struct Obj : instance<TyMutex__oo<>, Obj<T>> {
typon::Mutex mutex;
TyCell__oo<>::Obj<T> cell;
};
struct : method {
auto operator()(auto self, auto callback) -> typon::Task<TyNone> const {
auto lock = dot(self, mutex).lock();
co_await lock;
co_await callback(ref(dot(self, cell)));
co_return None;
}
} static constexpr when{};
template<typename T>
auto operator()(T val) const {
auto obj = referencemodel::meta::arc<Obj<T>>(std::in_place);
dot(obj, cell).val = val;
return obj;
static constexpr std::string_view name = "Mutex";
template <typename T> struct Obj : instance<TyMutex__oo<>, Obj<T>> {
typon::Mutex mutex;
TyCell__oo<>::Obj<T> cell;
};
struct : method {
using has_sync = std::true_type;
auto typon$$sync(auto, auto) -> TyNone const { return None; }
auto operator()(auto _self, auto callback) -> typon::Task<TyNone> const {
print("1"_ps);
auto self = arc(_self);
print("2"_ps);
auto lock = dot(self, mutex).lock();
print("3"_ps);
co_await lock;
print("4"_ps);
co_await callback(ref(dot(self, cell)));
print("5"_ps);
co_return None;
}
} static constexpr when{};
template <typename T> auto operator()(T val) const {
auto obj = referencemodel::meta::arc<Obj<T>>(std::in_place);
dot(obj, cell).val = val;
return obj;
}
};
template<typename T>
using ArcMutex = Arc<TyMutex__oo<>::template Obj<T>>;
template <typename T> using ArcMutex = Arc<TyMutex__oo<>::template Obj<T>>;
}
} // namespace typon
static constexpr typon::TyMutex__oo<> Mutex;
......
......@@ -10,6 +10,7 @@
namespace view = std::views;
#include <python/basedef.hpp>
#include "int.hpp"
auto stride = [](int n) {
return [s = -1, n](auto const &) mutable {
......@@ -30,7 +31,7 @@ struct range_s : TyBuiltin<range_s> {
auto End = Step < 0 ? Begin : std::max(start, stop);
return view::iota(Begin, End) | view::filter(stride(std::abs(Step))) |
view::transform([start, stop](std::size_t i) {
return start < stop ? i : stop - (i - start);
return typon::TyInt(start < stop ? i : stop - (i - start));
});
}
......
......@@ -23,30 +23,28 @@ struct TySlice__oo : classtype<_Base0, TySlice__oo<>> {
Stop stop;
Step step;
Obj(Start start, Stop stop, Step step) : start(start), stop(stop), step(step) {}
Obj(Start start, Stop stop, Step step)
: start(start), stop(stop), step(step) {}
};
template <typename Stop>
auto operator()(Stop stop) const {
template <typename Stop> auto operator()(Stop stop) const {
return Obj<TyNone, Stop, TyNone>{None, stop, None};
}
template <typename Start, typename Stop>
auto operator()(Start start, Stop stop) const {
template <typename Start, typename Stop>
auto operator()(Start start, Stop stop) const {
return Obj<Start, Stop, TyNone>{start, stop, None};
}
}
template <typename Start, typename Stop, typename Step>
auto operator()(Start start, Stop stop, Step step) const {
template <typename Start, typename Stop, typename Step>
auto operator()(Start start, Stop stop, Step step) const {
return Obj<Start, Stop, Step>{start, stop, step};
}
}
};
static constexpr TySlice__oo<> TySlice{};
}
} // namespace typon
/*struct TySlice {
TySlice() = default;
TySlice(const TySlice &) = default;
......
......@@ -177,14 +177,14 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
} static constexpr oo__len__oo{};
// getitem
struct : method {
auto operator()(auto self, auto index) const {
if (index < 0) {
index += self->value.size();
}
return Obj(self->value[index]);
}
} static constexpr oo__getitem__oo{};
struct : method {
auto operator()(auto self, auto index) const {
if (index < 0) {
index += self->value.size();
}
return Obj(self->value[index]);
}
} static constexpr oo__getitem__oo{};
/*struct : method {
auto operator()(auto self, auto other) const {
......
......@@ -185,17 +185,16 @@ struct socket__oo : referencemodel::moduletype<socket__oo<>> {
err != 0) {
system_error(err, "getaddrinfo()");
}
auto rlist = typon::TyList({
// make tuple (family, type, proto, canonname, sockaddr)
// (int, int, int, str, str)
std::make_tuple(
typon::TyInt(res->ai_family), typon::TyInt(res->ai_socktype),
typon::TyInt(res->ai_protocol),
typon::TyStr(res->ai_canonname ? res->ai_canonname : ""),
typon::TyStr(res->ai_addr ? res->ai_addr->sa_data : ""))
});
::freeaddrinfo(res);
return rlist;
auto rlist = typon::TyList(
{// make tuple (family, type, proto, canonname, sockaddr)
// (int, int, int, str, str)
std::make_tuple(
typon::TyInt(res->ai_family), typon::TyInt(res->ai_socktype),
typon::TyInt(res->ai_protocol),
typon::TyStr(res->ai_canonname ? res->ai_canonname : ""),
typon::TyStr(res->ai_addr ? res->ai_addr->sa_data : ""))});
::freeaddrinfo(res);
return rlist;
}
} static constexpr getaddrinfo{};
......
......@@ -15,9 +15,9 @@ struct time__oo : referencemodel::moduletype<time__oo<>> {
struct : referencemodel::function {
typon::Task<typon::TyNone> operator()(auto duration) const {
co_await typon::io::sleep(std::chrono::seconds(duration));
co_return None;
}
co_await typon::io::sleep(std::chrono::seconds(duration));
co_return None;
}
} static constexpr sleep{};
};
time__oo<> all;
......
from time import sleep
class Actor[T]:
mutex: Mutex[T]
def __init__(self, val: T):
self.mutex = Mutex(val)
def when[U](self, f: Callable[[Cell[T]], U]):
return future(lambda: self.mutex.when(f))
def inc(cell):
print("inc")
x = cell.val
sleep(1)
cell.val = x + 1
print("current:", cell.val)
def truc():
print("a")
a = Actor(0)
print("b")
for i in range(10):
print("spawn", i)
a.when(inc)
print("spawned", i)
future = a.when(lambda cell: print("final:", cell.val))
# future.get()
print("done")
if __name__ == "__main__":
print("Actor:")
truc()
\ No newline at end of file
......@@ -20,9 +20,7 @@ class Actor[T]:
mutex: Mutex[T]
def __init__(self, val: T):
print("l")
self.mutex = Mutex(val)
print("m")
# def when(self, f: Callable[[T], object]):
# return future(lambda: self.mutex.when(f))
......@@ -31,9 +29,7 @@ def thing(x):
print("hello", x)
if __name__ == "__main__":
print("j")
act = Actor(123)
print("k")
act.mutex.when(thing)
# class Actor[T]:
......
......@@ -22,13 +22,13 @@ def truc():
m = Mutex(0)
for _ in range(10):
fork(lambda: m.when(inc))
sync()
#sync()
def nomutex():
t = Thing(0)
for _ in range(10):
fork(lambda: t.inc())
sync()
#sync()
if __name__ == "__main__":
......
......@@ -64,7 +64,7 @@ def emit_class(name: str, node: ConcreteType) -> Iterable[str]:
yield "template <"
if node.generic_parent.parameters:
yield from join(",", (f"typename {name}" for name in node.generic_parent.parameters))
yield from join(",", (f"typename {p.name}" for p in node.generic_parent.parameters))
yield ", typename... $T"
else:
yield "typename... $T, typename _Void = void"
......
......@@ -127,8 +127,11 @@ class ExpressionVisitor(NodeVisitor):
assert len(node.args) == 1
arg = node.args[0]
assert isinstance(arg, ast.Lambda)
fixed = node.func.id
if fixed == "future": # Temporary until we separate the namespaces
fixed = "future_stdlib"
if self.generator != CoroutineMode.SYNC:
yield f"co_await typon::{node.func.id}("
yield f"co_await typon::{fixed}("
assert isinstance(arg.body, ast.Call)
yield from self.visit(arg.body.func)
yield "("
......@@ -136,7 +139,14 @@ class ExpressionVisitor(NodeVisitor):
yield ")"
yield ")"
else:
yield from self.visit(arg.body)
match node.func.id:
case "fork":
yield from self.visit(arg.body) # fork is transparent
case "future":
yield "typon::future_stdlib.typon$$sync("
yield from self.visit(arg.body)
yield ")"
return
if isinstance(node.func, ast.Name) and node.func.id == "sync":
......@@ -154,7 +164,8 @@ class ExpressionVisitor(NodeVisitor):
if self.generator != CoroutineMode.SYNC:
nty = node.type.resolve()
if isinstance(nty, ResolvedConcreteType) and (
nty.inherits(TY_FUTURE) or (
#nty.inherits(TY_FUTURE) or
(
is_get and nty.inherits(TY_FORKED)
)
):
......@@ -175,7 +186,7 @@ class ExpressionVisitor(NodeVisitor):
if is_get and node.func.value.type.inherits(TY_FUTURE, TY_FORKED):
yield "("
yield from self.visit(node.func.value)
yield ").get"
yield ")->get"
else:
yield from self.visit(node.func)
......@@ -252,10 +263,10 @@ class ExpressionVisitor(NodeVisitor):
templ, args, _ = self.process_args(node.args)
yield templ
yield args
yield "->"
yield "-> typon::Task<"
yield from self.visit(node.type.deref().return_type)
yield "{"
yield "return"
yield "> {"
yield "co_return"
yield from self.visit(node.body)
yield ";"
yield "}"
......
......@@ -9,7 +9,7 @@ from transpiler.phases.typing.exceptions import ArgumentCountMismatchError, Type
from transpiler.phases.typing.types import BaseType, TY_STR, TY_BOOL, TY_INT, TY_COMPLEX, TY_FLOAT, TY_NONE, \
ClassTypeType, ResolvedConcreteType, GenericType, CallableInstanceType, TY_LIST, TY_SET, TY_DICT, RuntimeValue, \
TypeVariable, TY_LAMBDA, TypeListType, MethodType, TY_TUPLE, GenericInstanceType, PROMISES, TRANSPARENT_PROMISES, \
TY_FORKED, TY_JOIN, TypeTupleType, TupleInstanceType, TY_TYPE, TY_SLICE
TY_FORKED, TY_JOIN, TypeTupleType, TupleInstanceType, TY_TYPE, TY_SLICE, BoundFuncTypeBase
from transpiler.phases.typing.scope import ScopeKind, VarDecl, VarKind
from transpiler.utils import linenodata
......@@ -166,6 +166,8 @@ class ScoperExprVisitor(ScoperVisitor):
raise TypeMismatchError(a, b, TypeMismatchKind.DIFFERENT_TYPE)
if not ftype.is_native:
if isinstance(ftype.generic_parent, BoundFuncTypeBase):
i += 1
pname = ftype.block_data.node.args.args[i].arg
ftype.block_data.scope.declare_local(pname, b)
......
......@@ -16,7 +16,7 @@ from transpiler.phases.typing.scope import Scope, VarDecl, VarKind, ScopeKind
from transpiler.phases.typing.types import BaseType, BuiltinGenericType, BuiltinType, create_builtin_generic_type, \
create_builtin_type, ConcreteType, GenericInstanceType, TypeListType, TypeTupleType, GenericParameter, \
GenericParameterKind, TypeVariable, ResolvedConcreteType, MemberDef, ClassTypeType, CallableInstanceType, \
MethodType, UniqueTypeMixin, GenericType, BlockData, TY_TASK, UserGenericType, UserType
MethodType, UniqueTypeMixin, GenericType, BlockData, TY_TASK, UserGenericType, UserType, BoundFuncTypeBase
from transpiler.phases.utils import NodeVisitorSeq
def visit_generic_item(
......@@ -254,7 +254,7 @@ class StdlibVisitor(NodeVisitorSeq):
if cur_class_ref is not None:
def remove_self(self, self_type):
class BoundFuncType(UniqueTypeMixin, GenericType):
class BoundFuncType(BoundFuncTypeBase, GenericType):
def name(self) -> str:
return f"BoundFuncType${node.name}"
......
......@@ -238,6 +238,9 @@ class UniqueTypeMixin:
def contains_internal(self, other: "BaseType") -> bool:
return self == other
class BoundFuncTypeBase(UniqueTypeMixin):
pass
@dataclass(eq=False)
class BuiltinType(UniqueTypeMixin, ResolvedConcreteType):
pass
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment