Commit 7fb2f104 authored by Tom Niget's avatar Tom Niget

Give up

parent 647b5c06
...@@ -62,95 +62,6 @@ template <PySmartPtr T> struct RealType<T> { ...@@ -62,95 +62,6 @@ template <PySmartPtr T> struct RealType<T> {
namespace typon { namespace typon {
// template <typename T> using TyObj = std::shared_ptr<typename
// RealType<T>::type>;
template <typename T>
class TyObj : public std::shared_ptr<typename RealType<T>::type> {
public:
using inner = typename RealType<T>::type;
/*template<typename... Args>
TyObj(Args&&... args) :
std::shared_ptr<inner>(std::make_shared<inner>(std::forward<Args>(args)...))
{}*/
TyObj() : std::shared_ptr<inner>() {}
TyObj(std::nullptr_t) : std::shared_ptr<inner>(nullptr) {}
TyObj(inner *ptr) : std::shared_ptr<inner>(ptr) {}
TyObj(const std::shared_ptr<inner> &ptr) : std::shared_ptr<inner>(ptr) {}
TyObj(std::shared_ptr<inner> &&ptr) : std::shared_ptr<inner>(ptr) {}
TyObj(const TyObj &ptr) : std::shared_ptr<inner>(ptr) {}
TyObj(TyObj &ptr) : std::shared_ptr<inner>(ptr) {}
TyObj(TyObj &&ptr) : std::shared_ptr<inner>(ptr) {}
TyObj &operator=(const TyObj &ptr) {
std::shared_ptr<inner>::operator=(ptr);
return *this;
}
TyObj &operator=(TyObj &&ptr) {
std::shared_ptr<inner>::operator=(ptr);
return *this;
}
TyObj &operator=(std::nullptr_t) {
std::shared_ptr<inner>::operator=(nullptr);
return *this;
}
TyObj &operator=(inner *ptr) {
std::shared_ptr<inner>::operator=(ptr);
return *this;
}
TyObj &operator=(const std::shared_ptr<inner> &ptr) {
std::shared_ptr<inner>::operator=(ptr);
return *this;
}
template <typename U>
TyObj(const TyObj<U> &ptr) : std::shared_ptr<inner>(ptr) {}
// TyObj(TyObj<U> &&ptr) : std::shared_ptr<inner>(ptr) {}
// using make_shared
/*template<class U>
TyObj(U&& other) : std::shared_ptr<inner>(std::make_shared<inner>(other)) {}*/
template <class U> bool operator==(const TyObj<U> &other) const {
// check null
if (this->get() == other.get()) {
return true;
}
if (this->get() == nullptr || other.get() == nullptr) {
return false;
}
return *this->get() == *other.get();
}
template <class U> bool operator==(const U &other) const {
if (this->get() == nullptr) {
return false;
}
return *this->get() == other;
}
template <class U> bool py_is(const TyObj<U> &other) const {
return this->get() == other.get();
}
};
template <typename T, typename... Args>
auto tyObj(Args &&...args) -> TyObj<typename RealType<T>::type> {
return std::make_shared<typename RealType<T>::type>(
std::forward<Args>(args)...);
}
template <typename T, typename... Args>
auto pyobj_agg(Args &&...args) -> TyObj<T> {
return std::make_shared<typename RealType<T>::type>(
(typename RealType<T>::type){std::forward<Args>(args)...});
}
class TyNone {}; class TyNone {};
} // namespace typon } // namespace typon
...@@ -169,7 +80,7 @@ concept PyIterable = requires(T t) { ...@@ -169,7 +80,7 @@ concept PyIterable = requires(T t) {
template <PyIterable T, PyIterator U> U iter(const T &t) { return t.py_iter(); } template <PyIterable T, PyIterator U> U iter(const T &t) { return t.py_iter(); }
template <typename T> /*template <typename T>
concept CppSize = requires(const T &t) { concept CppSize = requires(const T &t) {
{ t.size() } -> std::same_as<size_t>; { t.size() } -> std::same_as<size_t>;
}; };
...@@ -181,11 +92,16 @@ concept PyLen = requires(const T &t) { ...@@ -181,11 +92,16 @@ concept PyLen = requires(const T &t) {
template <CppSize T> template <CppSize T>
requires(!PyLen<T>) requires(!PyLen<T>)
size_t len(const T &t) { auto len(const T &t) {
return t.size(); return t.size();
} }
template <PyLen T> size_t len(const T &t) { return t.py_len(); } template <PyLen T> size_t len(const T &t) { return t.py_len(); }*/
template<typename T>
auto len(const T& t) {
return dot(t, oo__len__oo)();
}
template <typename T> template <typename T>
concept PyNext = requires(T t) { concept PyNext = requires(T t) {
...@@ -473,8 +389,8 @@ using InterpGuard = py::scoped_interpreter; ...@@ -473,8 +389,8 @@ using InterpGuard = py::scoped_interpreter;
template <typename T> template <typename T>
concept HasSync = requires(T t) { concept HasSync = requires(T t) {
{ t.sync() } -> std::same_as<T>; { t.sync() } -> std::same_as<T>;
}; };
/*auto call_sync(auto f, auto... args) { /*auto call_sync(auto f, auto... args) {
if constexpr (HasSync<decltype(f)>) { if constexpr (HasSync<decltype(f)>) {
...@@ -486,11 +402,12 @@ concept HasSync = requires(T t) { ...@@ -486,11 +402,12 @@ concept HasSync = requires(T t) {
auto call_sync(auto f) { auto call_sync(auto f) {
if constexpr (HasSync<decltype(f)>) { if constexpr (HasSync<decltype(f)>) {
return [f](auto... args) { return f.sync(std::forward<decltype(args)>(args)...); }; return [f](auto... args) {
return f.sync(std::forward<decltype(args)>(args)...);
};
} else { } else {
return f; return f;
} }
} }
#endif // TYPON_BUILTINS_HPP #endif // TYPON_BUILTINS_HPP
...@@ -149,45 +149,45 @@ using namespace referencemodel; ...@@ -149,45 +149,45 @@ using namespace referencemodel;
template <typename _Base0 = object> template <typename _Base0 = object>
struct TyDict__oo : classtype<_Base0, TyDict__oo<>> { struct TyDict__oo : classtype<_Base0, TyDict__oo<>> {
struct : method { struct : method {
template <typename Self> auto operator()(Self self) const { template <typename Self> auto operator()(Self self) const {
std::stringstream s; std::stringstream s;
s << '{'; s << '{';
if (self->_m->size() > 0) { if (self->_m->size() > 0) {
s << repr(self->_m->begin()->first)->value; s << repr(self->_m->begin()->first)->value;
s << ": "; s << ": ";
s << repr(self->_m->begin()->second)->value; s << repr(self->_m->begin()->second)->value;
for (auto it = ++self->_m->begin(); it != self->_m->end(); it++) { for (auto it = ++self->_m->begin(); it != self->_m->end(); it++) {
s << ", "; s << ", ";
s << repr(it->first)->value; s << repr(it->first)->value;
s << ": "; s << ": ";
s << repr(it->second)->value; s << repr(it->second)->value;
} }
} }
s << '}'; s << '}';
return typon::TyStr__oo<>::Obj(s.str()); return typon::TyStr__oo<>::Obj(s.str());
} }
} static constexpr oo__repr__oo{}; } static constexpr oo__repr__oo{};
static constexpr auto oo__str__oo = oo__repr__oo; static constexpr auto oo__str__oo = oo__repr__oo;
template <typename K, typename V> struct Obj : instance<TyDict__oo<>, Obj<K, V>> { template <typename K, typename V>
struct Obj : instance<TyDict__oo<>, Obj<K, V>> {
std::shared_ptr<std::unordered_map<K, V>> _m; std::shared_ptr<std::unordered_map<K, V>> _m;
Obj(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {} Obj(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {}
Obj(std::unordered_map<K, V> &&m) Obj(std::unordered_map<K, V> &&m)
: _m(std::move( : _m(std::move(
std::make_shared<std::unordered_map<K, V>>(std::move(m)))) {} std::make_shared<std::unordered_map<K, V>>(std::move(m)))) {}
Obj(std::initializer_list<std::pair<K, V>> &&m) Obj(std::initializer_list<std::pair<K, V>> &&m)
: _m(std::make_shared<std::unordered_map<K, V>>(std::move(m))) {} : _m(std::make_shared<std::unordered_map<K, V>>(std::move(m))) {}
Obj() : _m(std::make_shared<std::unordered_map<K, V>>()) {} Obj() : _m(std::make_shared<std::unordered_map<K, V>>()) {}
template <typename... Args> template <typename... Args>
Obj(Args &&...args) Obj(Args &&...args)
: _m(std::make_shared<std::unordered_map<K, V>>( : _m(std::make_shared<std::unordered_map<K, V>>(
std::forward<Args>(args)...)) {} std::forward<Args>(args)...)) {}
}; };
template <typename T> auto operator()(std::initializer_list<T> &&v) const { template <typename T> auto operator()(std::initializer_list<T> &&v) const {
......
...@@ -81,11 +81,11 @@ struct TyInt__oo : classtype<_Base0, TyInt__oo<>> { ...@@ -81,11 +81,11 @@ struct TyInt__oo : classtype<_Base0, TyInt__oo<>> {
} }
} static constexpr oo__str__oo{}; } static constexpr oo__str__oo{};
struct : method { struct : method {
auto operator()(auto self, auto other) const { auto operator()(auto self, auto other) const {
return TyBool(dot(self, value) == dot(other, value)); return TyBool(dot(self, value) == dot(other, value));
} }
} static constexpr oo__eq__oo{}; } static constexpr oo__eq__oo{};
static constexpr auto oo__repr__oo = oo__str__oo; static constexpr auto oo__repr__oo = oo__str__oo;
......
...@@ -17,22 +17,20 @@ template <typename _Base0 = object> ...@@ -17,22 +17,20 @@ template <typename _Base0 = object>
struct TyList__oo : classtype<_Base0, TyList__oo<>> { struct TyList__oo : classtype<_Base0, TyList__oo<>> {
struct : method { struct : method {
template <typename Self> auto operator()(Self self) const { auto operator()(auto self) const {
return TyList__oo<>{}(self->_v); return TyList__oo<>{}(self->_v);
} }
} static constexpr copy{}; } static constexpr copy{};
struct : method { struct : method {
template <typename Self, typename Other> auto operator()(auto self, auto other) const {
auto operator()(Self self, Other other) const {
self->_v.reserve(self->_v.size() + other.size()); self->_v.reserve(self->_v.size() + other.size());
self->_v.insert(self->_v.end(), other.begin(), other.end()); self->_v.insert(self->_v.end(), other.begin(), other.end());
} }
} static constexpr extend{}; } static constexpr extend{};
struct : method { struct : method {
template <typename Self, typename Other> auto operator()(auto self, auto other) const {
auto operator()(Self self, Other other) const {
auto result = TyList__oo<>{}(self->_v); auto result = TyList__oo<>{}(self->_v);
dot(result, extend)(other); dot(result, extend)(other);
return result; return result;
...@@ -40,8 +38,7 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> { ...@@ -40,8 +38,7 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> {
} static constexpr oo__add__oo{}; } static constexpr oo__add__oo{};
struct : method { struct : method {
template <typename Self, typename Other> auto operator()(auto self, auto other) const {
auto operator()(Self self, Other other) const {
auto result = TyList__oo<>{}(self->_v); auto result = TyList__oo<>{}(self->_v);
result->_v->reserve(result->_v->size() * other); result->_v->reserve(result->_v->size() * other);
for (int i = 0; i < other - 1; i++) { for (int i = 0; i < other - 1; i++) {
...@@ -52,7 +49,7 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> { ...@@ -52,7 +49,7 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> {
} static constexpr oo__mul__oo{}; } static constexpr oo__mul__oo{};
struct : method { struct : method {
template <typename Self> auto operator()(Self self) const { auto operator()(auto self) const {
std::stringstream s; std::stringstream s;
s << '['; s << '[';
if (self->_v->size() > 0) { if (self->_v->size() > 0) {
...@@ -69,6 +66,23 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> { ...@@ -69,6 +66,23 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> {
static constexpr auto oo__str__oo = oo__repr__oo; static constexpr auto oo__str__oo = oo__repr__oo;
struct : method {
auto operator()(auto self) const { return typon::TyInt(self->_v->size()); }
} static constexpr oo__len__oo{};
// getitem
struct : method {
auto operator()(auto self, auto i) const {
if (i < 0) {
i += self->_v->size();
}
if (i < 0 || i >= self->_v->size()) {
throw std::out_of_range("list index out of range");
}
return self->_v->operator[](i);
}
} static constexpr oo__getitem__oo{};
template <typename T> struct Obj : instance<TyList__oo<>, Obj<T>> { template <typename T> struct Obj : instance<TyList__oo<>, Obj<T>> {
using value_type = T; using value_type = T;
......
...@@ -173,6 +173,10 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> { ...@@ -173,6 +173,10 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
} }
} static constexpr oo__repr__oo{}; } static constexpr oo__repr__oo{};
struct : method {
auto operator()(auto self) const { return (self->value.size()); }
} static constexpr oo__len__oo{};
struct Obj : value<TyStr__oo<>, Obj> { struct Obj : value<TyStr__oo<>, Obj> {
std::string value; std::string value;
......
...@@ -826,8 +826,8 @@ private: ...@@ -826,8 +826,8 @@ private:
template <typename T, typename O> struct instance : T { template <typename T, typename O> struct instance : T {
using type = T; using type = T;
static constexpr std::string_view repr = /*static constexpr std::string_view repr =
meta::join<object::object_of_, T::repr>; meta::join<object::object_of_, T::repr>;*/
const O *operator->() const { return static_cast<const O *>(this); } const O *operator->() const { return static_cast<const O *>(this); }
O *operator->() { return static_cast<O *>(this); } O *operator->() { return static_cast<O *>(this); }
...@@ -839,7 +839,7 @@ template <typename B, typename T> struct classtype : B { ...@@ -839,7 +839,7 @@ template <typename B, typename T> struct classtype : B {
using base = B; using base = B;
using type = T; using type = T;
static constexpr std::string_view repr = meta::join<object::class_, T::name>; //static constexpr std::string_view repr = meta::join<object::class_, T::name>;
const T *operator->() const { return static_cast<const T *>(this); } const T *operator->() const { return static_cast<const T *>(this); }
T *operator->() { return static_cast<T *>(this); } T *operator->() { return static_cast<T *>(this); }
...@@ -866,7 +866,7 @@ using rebase = typename rebase_s<std::remove_cvref_t<T>>::template type<Rebase>; ...@@ -866,7 +866,7 @@ using rebase = typename rebase_s<std::remove_cvref_t<T>>::template type<Rebase>;
template <typename M> struct moduletype : object { template <typename M> struct moduletype : object {
using type = M; using type = M;
static constexpr std::string_view repr = meta::join<object::module_, M::name>; //static constexpr std::string_view repr = meta::join<object::module_, M::name>;
const M *operator->() const { return static_cast<const M *>(this); } const M *operator->() const { return static_cast<const M *>(this); }
M *operator->() { return static_cast<M *>(this); } M *operator->() { return static_cast<M *>(this); }
...@@ -1074,15 +1074,15 @@ namespace meta { ...@@ -1074,15 +1074,15 @@ namespace meta {
#define SIMPLE_OP(OP, DUNDER) \ #define SIMPLE_OP(OP, DUNDER) \
namespace meta { \ namespace meta { \
template <typename Left, typename Right> \ template <typename Left, typename Right> \
concept DUNDER##able = requires(Left left, Right right) { \ concept DUNDER##able = requires(Left left, Right right) { \
left->oo__##DUNDER##__oo(left, right); \ left->oo__##DUNDER##__oo(left, right); \
}; \ }; \
} \ } \
template <meta::object Left, meta::object Right> \ template <meta::object Left, meta::object Right> \
requires meta::DUNDER \ requires meta::DUNDER \
##able<Left, Right> auto operator OP(Left &&left, Right &&right) { \ ##able<Left, Right> auto operator OP(Left &&left, Right &&right) { \
return dot(std::forward<Left>(left), \ return dot(std::forward<Left>(left), \
oo__##DUNDER##__oo)(std::forward<Right>(right)); \ oo__##DUNDER##__oo)(std::forward<Right>(right)); \
} }
/*template <typename Left, typename Right> /*template <typename Left, typename Right>
...@@ -1139,6 +1139,24 @@ SIMPLE_OP(!=, ne) ...@@ -1139,6 +1139,24 @@ SIMPLE_OP(!=, ne)
SIMPLE_OP(>, gt) SIMPLE_OP(>, gt)
SIMPLE_OP(>=, ge) SIMPLE_OP(>=, ge)
namespace meta {
template <typename Left, typename Right>
concept DUNDERgetitemable = requires(Left left, Right right) {
left->oo__getitem__oo(left, right);
};
template <typename Left, typename Right>
concept DUNDERsetitemable = requires(Left left, Right right) {
left->oo__setitem__oo(left, right);
};
}
/* template <meta::object Left, meta::object Right>
requires meta::DUNDERgetitemable<Left, Right> auto operator [](Left &&left, Right &&right) {
return dot(std::forward<Left>(left),
oo__getitem__oo)(std::forward<Right>(right));
}*/
// todo: setitem?
} // namespace referencemodel } // namespace referencemodel
#endif // REFERENCEMODEL_H #endif // REFERENCEMODEL_H
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
#include <tuple> #include <tuple>
namespace py_socket { namespace py_socket {
struct socket_t { template <typename _Unused = void>
struct socket__oo : referencemodel::moduletype<socket__oo<>> {
#undef SOCK_STREAM #undef SOCK_STREAM
#undef AF_INET6 #undef AF_INET6
#undef SOL_SOCKET #undef SOL_SOCKET
...@@ -23,81 +24,137 @@ struct socket_t { ...@@ -23,81 +24,137 @@ struct socket_t {
static constexpr int SO_REUSEADDR = 2; static constexpr int SO_REUSEADDR = 2;
static constexpr int AF_UNIX = 1; static constexpr int AF_UNIX = 1;
struct socket_s { template <typename _Base0 = object>
struct py_type { struct socket_t__oo : referencemodel::classtype<_Base0, socket_t__oo<>> {
METHOD(typon::Task<std::tuple<TyObj<py_type> COMMA() std::string>>,
accept, (Self self), { static auto create_socket(auto fd) {
int connfd = co_await typon::io::accept(self->fd, NULL, NULL); struct Obj : referencemodel::instance<socket_t__oo<>, Obj> {
if (connfd < 0) { /*Obj(int fd = -1) : fd(fd) {}
system_error(-connfd, "accept()");
} Obj(const Obj &other) : fd(other.fd) {}*/
co_return std::make_tuple(tyObj<py_type>(connfd),
std::string("")); // TODO int fd;
}) };
return Obj{fd};
METHOD(typon::Task<void>, close, (Self self), }
{ co_await typon::io::close(self->fd); })
METHOD(void, listen, (Self self, int backlog), { struct : referencemodel::method {
auto operator()(auto self) -> typon::Task<
std::tuple<decltype(rc(create_socket(-1))), decltype(""_ps)>> const {
int connfd = co_await typon::io::accept(self->fd, NULL, NULL);
if (connfd < 0) {
system_error(-connfd, "accept()");
}
co_return std::make_tuple(rc(create_socket(connfd)),
""_ps); // TODO
}
} static constexpr accept{};
struct : referencemodel::method {
auto operator()(auto self, int level, int optname, int optval) const {
if (::setsockopt(self->fd, level, optname, &optval, sizeof(int)) < 0) {
system_error(errno, "setsockopt()");
}
return typon::TyNone{};
}
} static constexpr setsockopt{};
// bind
struct : referencemodel::method {
auto operator()(auto self, std::tuple<std::string, int> address) const {
auto [host, port] = address;
sockaddr_in6 addr;
std::memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
addr.sin6_addr = in6addr_any;
if (::bind(self->fd, (const sockaddr *)&addr, sizeof(addr)) < 0) {
system_error(errno, "bind()");
}
return typon::TyNone{};
}
} static constexpr bind{};
struct : referencemodel::method {
typon::Task<typon::TyNone> operator()(auto self, int backlog) const {
if (::listen(self->fd, backlog) < 0) { if (::listen(self->fd, backlog) < 0) {
dotp(self, close)(); co_await dot(self, close)();
system_error(errno, "listen()"); system_error(errno, "listen()");
} }
}) co_return {};
}
METHOD(void, setsockopt, (Self self, int level, int optname, int optval), } static constexpr listen{};
{
if (::setsockopt(self->fd, level, optname, &optval,
sizeof(int)) < 0) {
system_error(errno, "setsockopt()");
}
})
METHOD(void, bind,
(Self self, std::tuple<std::string COMMA() int> address), {
auto [host, port] = address;
sockaddr_in6 addr;
std::memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
addr.sin6_addr = in6addr_any;
if (::bind(self->fd, (const sockaddr *)&addr, sizeof(addr)) <
0) {
system_error(errno, "bind()");
}
})
METHOD(typon::Task<TyBytes>, recv, (Self self, int bufsize), {
TyBytes buf(bufsize, '\0');
co_await typon::io::recv(self->fd, buf.data(), buf.size(), 0);
co_return std::move(buf);
})
METHOD(typon::Task<void>, send, (Self self, TyBytes data), {
if (int sbytes = co_await typon::io::send(self->fd, data, 0);
sbytes < 0) {
co_await dotp(self, close)();
system_error(-sbytes, "send()");
}
})
py_type(int fd = -1) : fd(fd) {} struct : referencemodel::method {
typon::Task<typon::TyNone> operator()(auto self) const {
co_await typon::io::close(self->fd);
co_return {};
}
} static constexpr close{};
/*METHOD(typon::Task<void>, close, (Self self),
{ co_await typon::io::close(self->fd); })
METHOD(void, listen, (Self self, int backlog), {
if (::listen(self->fd, backlog) < 0) {
dotp(self, close)();
system_error(errno, "listen()");
}
})
METHOD(void, setsockopt, (Self self, int level, int optname, int optval),
{
if (::setsockopt(self->fd, level, optname, &optval,
sizeof(int)) < 0) {
system_error(errno, "setsockopt()");
}
})
METHOD(void, bind,
(Self self, std::tuple<std::string COMMA() int> address), {
auto [host, port] = address;
sockaddr_in6 addr;
std::memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port);
addr.sin6_addr = in6addr_any;
if (::bind(self->fd, (const sockaddr *)&addr, sizeof(addr)) <
0) {
system_error(errno, "bind()");
}
})
METHOD(typon::Task<TyBytes>, recv, (Self self, int bufsize), {
TyBytes buf(bufsize, '\0');
co_await typon::io::recv(self->fd, buf.data(), buf.size(), 0);
co_return std::move(buf);
})
METHOD(typon::Task<void>, send, (Self self, TyBytes data), {
if (int sbytes = co_await typon::io::send(self->fd, data, 0);
sbytes < 0) {
co_await dotp(self, close)();
system_error(-sbytes, "send()");
}
})*/
auto operator()(int family, int type_) const {
py_type(const py_type &other) : fd(other.fd) {}
int fd;
};
auto operator()(int family, int type_) {
if (int fd = ::socket(family, type_, 0); fd >= 0) { if (int fd = ::socket(family, type_, 0); fd >= 0) {
return tyObj<py_type>(fd); return rc(create_socket(fd));
} else { } else {
system_error(errno, "socket()"); system_error(errno, "socket()");
} }
} }
} socket;
FUNCTION(auto, getaddrinfo, };
static constexpr socket_t__oo<> socket{};
/*FUNCTION(auto, getaddrinfo,
(std::string host, int port, int family = 0, int type_ = 0, (std::string host, int port, int family = 0, int type_ = 0,
int proto = 0, int flags = 0), int proto = 0, int flags = 0),
{ {
...@@ -116,14 +173,13 @@ struct socket_t { ...@@ -116,14 +173,13 @@ struct socket_t {
system_error(err, "getaddrinfo()"); system_error(err, "getaddrinfo()");
} }
return res; return res;
}) })*/
} all; };
socket__oo<> all;
auto &get_all() { return all; }
} // namespace py_socket } // namespace py_socket
namespace typon { namespace typon {
using PySocket = TyObj<py_socket::socket_t::socket_s>; // using PySocket = TyObj<py_socket::socket_t::socket_s>;
} }
#endif // TYPON_SOCKET_HPP #endif // TYPON_SOCKET_HPP
...@@ -9,16 +9,20 @@ ...@@ -9,16 +9,20 @@
#include <iostream> #include <iostream>
namespace py_sys { namespace py_sys {
struct sys_t { template <typename _Unused = void>
struct sys__oo : referencemodel::moduletype<sys__oo<>> {
static constexpr auto &stdin = std::cin; static constexpr auto &stdin = std::cin;
static constexpr auto &stdout = std::cout; static constexpr auto &stdout = std::cout;
static constexpr auto &stderr = std::cerr; static constexpr auto &stderr = std::cerr;
typon::TyList__oo<>::Obj<typon::TyStr__oo<>::Obj> argv; typon::TyList__oo<>::Obj<typon::TyStr__oo<>::Obj> argv;
FUNCTION(void, exit, (int code), { std::exit(code); }) /*FUNCTION(void, exit, (int code), { std::exit(code); })*/
} all;
auto &get_all() { return all; } struct : referencemodel::function {
typon::TyNone operator()(int code) const { std::exit(code); }
} static constexpr exit{};
};
sys__oo<> all;
} // namespace py_sys } // namespace py_sys
#endif // TYPON_SYS_HPP #endif // TYPON_SYS_HPP
...@@ -179,4 +179,40 @@ def exit(code: int | None = None) -> None: ... ...@@ -179,4 +179,40 @@ def exit(code: int | None = None) -> None: ...
class Exception: class Exception:
def __init__(self, message: str) -> None: ... def __init__(self, message: str) -> None: ...
assert next([]) assert next([])
\ No newline at end of file
from typing import Callable
class Task[T]:
pass
class Join[T]:
pass
class Forked[T]:
def get(self) -> T: ...
class Future[T]:
def get(self) -> Task[T]: ...
assert Forked[int].get
def fork[T](f: Callable[[], T]) -> Task[Forked[T]]:
# stub
class Res:
get = f
return Res
assert fork(lambda: 1).get
def future[T](f: Callable[[], T]) -> Task[Future[T]]:
# stub
class Res:
get = f
return Res
def sync() -> None:
# stub
pass
\ No newline at end of file
from typing import Callable
class Task[T]:
pass
class Join[T]:
pass
class Forked[T]:
def get(self) -> T: ...
class Future[T]:
def get(self) -> Task[T]: ...
assert Forked[int].get
def fork[T](f: Callable[[], T]) -> Task[Forked[T]]:
# stub
class Res:
get = f
return Res
assert fork(lambda: 1).get
def future[T](f: Callable[[], T]) -> Task[Future[T]]:
# stub
class Res:
get = f
return Res
def sync() -> None:
# stub
pass
def is_cpp() -> bool: def is_cpp() -> bool:
return False return False
...@@ -5,8 +5,11 @@ ...@@ -5,8 +5,11 @@
# #
# #
# @dataclass # @dataclass
# class Thing[T]: class Thing[T]:
# x: T x: T
def __init__(self, y):
pass
# def f[T](x: T): # def f[T](x: T):
...@@ -15,12 +18,9 @@ ...@@ -15,12 +18,9 @@
# #
# #
# #
# if __name__ == "__main__":
# a = Thing[int](1)
# b = Thing[str]("abc")
# print(a)
# print(b)
if __name__ == "__main__": if __name__ == "__main__":
print("abc") a = Thing(1)
\ No newline at end of file b = Thing("abc")
print(a)
print(b)
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
import sys import sys
from socket import socket, SOCK_STREAM, AF_INET6, SOL_SOCKET, SO_REUSEADDR from socket import socket, SOCK_STREAM, AF_INET6, SOL_SOCKET, SO_REUSEADDR
from typon import fork #from typon import fork
#fork = lambda x: x() #fork = lambda x: x()
...@@ -40,18 +40,19 @@ def handle_connection(connfd, filepath): ...@@ -40,18 +40,19 @@ def handle_connection(connfd, filepath):
def server_loop(sockfd, filepath): def server_loop(sockfd, filepath):
while True: while True:
connfd, _ = sockfd.accept() x = sockfd.accept()
fork(lambda: handle_connection(connfd, filepath)) #fork(lambda: handle_connection(connfd, filepath))
if __name__ == "__main__": if __name__ == "__main__":
PORT = 8000 PORT = 8000
if len(sys.argv) > 2: # if len(sys.argv) > 2:
print("Usage: webserver [ filepath ]") # print("Usage: webserver [ filepath ]")
sys.exit(1) # sys.exit(1)
filepath = sys.argv[1] if len(sys.argv) == 2 else "requirements.txt" #filepath = sys.argv[1] if len(sys.argv) == 2 else "requirements.txt"
filepath = "requirements.txt"
print("Serving", filepath, "on port", PORT) print("Serving", filepath, "on port", PORT)
sockfd = create_listening_socket(PORT) sockfd = create_listening_socket(PORT)
......
import ast import ast
from typing import Iterable from typing import Iterable
from transpiler.phases.typing.types import ConcreteType
def emit_class(node: ast.ClassDef) -> Iterable[str]:
def emit_class(name: str, node: ConcreteType) -> Iterable[str]:
yield f"template <typename _Base0 = referencemodel::object>" yield f"template <typename _Base0 = referencemodel::object>"
yield f"struct {node.name}__oo : referencemodel::classtype<_Base0, {node.name}__oo<>> {{" yield f"struct {name}__oo : referencemodel::classtype<_Base0, {name}__oo<>> {{"
yield f"static constexpr std::string_view name = \"{node.name}\";" yield f"static constexpr std::string_view name = \"{name}\";"
inner = ClassInnerVisitor2(node.inner_scope) # inner = ClassInnerVisitor2(node.inner_scope)
for stmt in node.body: # for stmt in node.body:
yield from inner.visit(stmt) # yield from inner.visit(stmt)
yield f"struct Obj : referencemodel::instance<{node.name}__oo<>, Obj> {{" yield f"struct Obj : referencemodel::instance<{name}__oo<>, Obj> {{"
inner = ClassInnerVisitor4(node.inner_scope) # inner = ClassInnerVisitor4(node.inner_scope)
for stmt in node.body: # for stmt in node.body:
yield from inner.visit(stmt) # yield from inner.visit(stmt)
yield "template <typename... U>" yield "template <typename... U>"
yield "Obj(U&&... args) {" yield "Obj(U&&... args) {"
...@@ -31,5 +33,5 @@ def emit_class(node: ast.ClassDef) -> Iterable[str]: ...@@ -31,5 +33,5 @@ def emit_class(node: ast.ClassDef) -> Iterable[str]:
yield "}" yield "}"
yield f"}};" yield f"}};"
yield f"static constexpr {node.name}__oo<> {node.name} {{}};" yield f"static constexpr {name}__oo<> {name} {{}};"
yield f"static_assert(sizeof {node.name} == 1);" yield f"static_assert(sizeof {name} == 1);"
\ No newline at end of file \ No newline at end of file
...@@ -5,6 +5,7 @@ from typing import Iterable ...@@ -5,6 +5,7 @@ from typing import Iterable
from transpiler.phases.emit_cpp.visitors import NodeVisitor, CoroutineMode, join from transpiler.phases.emit_cpp.visitors import NodeVisitor, CoroutineMode, join
from transpiler.phases.typing.scope import Scope from transpiler.phases.typing.scope import Scope
from transpiler.phases.typing.types import ClassTypeType
from transpiler.phases.utils import make_lnd from transpiler.phases.utils import make_lnd
from transpiler.utils import linenodata from transpiler.utils import linenodata
...@@ -121,6 +122,22 @@ class ExpressionVisitor(NodeVisitor): ...@@ -121,6 +122,22 @@ class ExpressionVisitor(NodeVisitor):
yield ")" yield ")"
def visit_Call(self, node: ast.Call) -> Iterable[str]: def visit_Call(self, node: ast.Call) -> Iterable[str]:
if isinstance(node.func, ast.Name) and node.func.id == "fork":
assert len(node.args) == 1
arg = node.args[0]
assert isinstance(arg, ast.Lambda)
if self.generator != CoroutineMode.SYNC:
yield "co_await typon::fork("
assert isinstance(arg.body, ast.Call)
yield from self.visit(arg.body.func)
yield "("
yield from join(", ", map(self.visit, arg.body.args))
yield ")"
yield ")"
else:
yield from self.visit(arg.body)
return
# async : co_await f(args) # async : co_await f(args)
# sync : call_sync(f, args) # sync : call_sync(f, args)
if self.generator != CoroutineMode.SYNC: if self.generator != CoroutineMode.SYNC:
...@@ -280,9 +297,9 @@ class ExpressionVisitor(NodeVisitor): ...@@ -280,9 +297,9 @@ class ExpressionVisitor(NodeVisitor):
yield "{}" yield "{}"
def visit_Subscript(self, node: ast.Subscript) -> Iterable[str]: def visit_Subscript(self, node: ast.Subscript) -> Iterable[str]:
# if isinstance(node.type, TypeType) and isinstance(node.type.type_object, MonomorphizedUserType): if isinstance(node.type, ClassTypeType):
# yield node.type.type_object.name yield from self.visit_BaseType(node.type.inner_type)
# return return
yield "(" yield "("
yield from self.visit(node.value) yield from self.visit(node.value)
yield ")[" yield ")["
......
...@@ -26,14 +26,19 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]: ...@@ -26,14 +26,19 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]:
yield "->" yield "->"
yield rty yield rty
yield " {" yield " {"
for rd in func.block_data.scope.root_decls: for var, initval in func.block_data.scope.root_decls.items():
pass yield "decltype("
yield from ExpressionVisitor(func.block_data.scope, mode).visit(initval)
yield ")"
yield var
yield ";"
yield from BlockVisitor(func.block_data.scope, generator=mode).visit(func.block_data.node.body) yield from BlockVisitor(func.block_data.scope, generator=mode).visit(func.block_data.node.body)
if mode == CoroutineMode.SYNC: if not getattr(func.block_data.scope, "has_return", False):
yield "return" if mode == CoroutineMode.SYNC:
else: yield "return"
yield "co_return" else:
yield "{};" yield "co_return"
yield "{};"
yield "}" yield "}"
rty = func.return_type.generic_args[0] rty = func.return_type.generic_args[0]
...@@ -47,7 +52,7 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]: ...@@ -47,7 +52,7 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]:
yield"decltype(sync(" yield"decltype(sync("
yield from join(",", (arg.arg for arg in func.block_data.node.args.args)) yield from join(",", (arg.arg for arg in func.block_data.node.args.args))
yield "))" yield "))"
yield ")" yield ">"
rty_code = " ".join(task_type()) rty_code = " ".join(task_type())
else: else:
pass pass
...@@ -293,6 +298,8 @@ class BlockVisitor(NodeVisitor): ...@@ -293,6 +298,8 @@ class BlockVisitor(NodeVisitor):
yield "return " yield "return "
if node.value: if node.value:
yield from self.expr().visit(node.value) yield from self.expr().visit(node.value)
else:
yield "typon::TyNone{}"
yield ";" yield ";"
import ast
from typing import Iterable from typing import Iterable
from transpiler.phases.emit_cpp.class_ import emit_class from transpiler.phases.emit_cpp.class_ import emit_class
...@@ -9,7 +10,19 @@ from transpiler.phases.typing.types import CallableInstanceType, ClassTypeType, ...@@ -9,7 +10,19 @@ from transpiler.phases.typing.types import CallableInstanceType, ClassTypeType,
def emit_module(mod: ModuleType) -> Iterable[str]: def emit_module(mod: ModuleType) -> Iterable[str]:
yield "#include <python/builtins.hpp>" yield "#include <python/builtins.hpp>"
yield "#include <python/sys.hpp>" yield "#include <python/sys.hpp>"
incl_vars = []
for node in mod.block_data.node.body:
match node:
case ast.Import(names):
for alias in names:
yield f"#include <python/{alias.name}.hpp>"
incl_vars.append(f"auto& {alias.asname or alias.name} = py_{alias.name}::all;")
case ast.ImportFrom(module, names, _):
yield f"#include <python/{module}.hpp>"
for alias in names:
incl_vars.append(f"auto& {alias.asname or alias.name} = py_{module}::all.{alias.name};")
yield "namespace PROGRAMNS {" yield "namespace PROGRAMNS {"
yield from incl_vars
yield "template <typename _Unused = void>" yield "template <typename _Unused = void>"
yield f"struct {mod.name()}__oo : referencemodel::moduletype<{mod.name()}__oo<>>" yield f"struct {mod.name()}__oo : referencemodel::moduletype<{mod.name()}__oo<>>"
yield "{" yield "{"
...@@ -18,13 +31,13 @@ def emit_module(mod: ModuleType) -> Iterable[str]: ...@@ -18,13 +31,13 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
continue continue
ty = field.type.deref() ty = field.type.deref()
from transpiler.phases.typing.expr import ScoperExprVisitor from transpiler.phases.typing.expr import ScoperExprVisitor
ScoperExprVisitor(ty.block_data.scope).visit_function_call(ty, [TypeVariable() for _ in ty.parameters])
x = 5 x = 5
match ty: match ty:
case CallableInstanceType(): case CallableInstanceType():
ScoperExprVisitor(ty.block_data.scope).visit_function_call(ty, [TypeVariable() for _ in ty.parameters])
yield from emit_function(name, ty) yield from emit_function(name, ty)
case ClassTypeType(): case ClassTypeType(inner_type):
yield from emit_class(ty) yield from emit_class(name, inner_type)
case _: case _:
raise NotImplementedError(f"Unsupported module item type {ty}") raise NotImplementedError(f"Unsupported module item type {ty}")
......
...@@ -8,6 +8,9 @@ from transpiler.phases.typing.exceptions import UnresolvedTypeVariableError ...@@ -8,6 +8,9 @@ from transpiler.phases.typing.exceptions import UnresolvedTypeVariableError
from transpiler.phases.typing.types import BaseType from transpiler.phases.typing.types import BaseType
from transpiler.utils import UnsupportedNodeError, highlight from transpiler.utils import UnsupportedNodeError, highlight
MAPPINGS = {
}
class UniversalVisitor: class UniversalVisitor:
def visit(self, node): def visit(self, node):
...@@ -51,8 +54,7 @@ class NodeVisitor(UniversalVisitor): ...@@ -51,8 +54,7 @@ class NodeVisitor(UniversalVisitor):
def fix_name(self, name: str) -> str: def fix_name(self, name: str) -> str:
if name.startswith("__") and name.endswith("__"): if name.startswith("__") and name.endswith("__"):
return f"py_{name[2:-2]}" return f"py_{name[2:-2]}"
return name return MAPPINGS.get(name, name)
#return MAPPINGS.get(name, name)
def visit_BaseType(self, node: BaseType) -> Iterable[str]: def visit_BaseType(self, node: BaseType) -> Iterable[str]:
node = node.resolve() node = node.resolve()
...@@ -63,11 +65,11 @@ class NodeVisitor(UniversalVisitor): ...@@ -63,11 +65,11 @@ class NodeVisitor(UniversalVisitor):
case types.TY_FLOAT: case types.TY_FLOAT:
yield "double" yield "double"
case types.TY_BOOL: case types.TY_BOOL:
yield "bool" yield "decltype(typon::TyBool(true))"
case types.TY_NONE: case types.TY_NONE:
yield "typon::TyNone" yield "typon::TyNone"
case types.TY_STR: case types.TY_STR:
yield "typon::TyStr" yield 'decltype(""_ps)'
case types.TypeVariable(name): case types.TypeVariable(name):
yield f"$VAR__{name}" yield f"$VAR__{name}"
...@@ -77,12 +79,12 @@ class NodeVisitor(UniversalVisitor): ...@@ -77,12 +79,12 @@ class NodeVisitor(UniversalVisitor):
yield "<" yield "<"
yield from join(",", map(self.visit, node.generic_args)) yield from join(",", map(self.visit, node.generic_args))
yield ">" yield ">"
case types.TY_LIST: # case types.TY_LIST:
yield "typon::TyList" # yield "typon::TyList"
case types.TY_DICT: # case types.TY_DICT:
yield "typon::TyDict" # yield "typon::TyDict"
case types.TY_SET: # case types.TY_SET:
yield "typon::TySet" # yield "typon::TySet"
case types.TY_TASK: case types.TY_TASK:
yield "typon::Task" yield "typon::Task"
case types.TY_JOIN: case types.TY_JOIN:
......
...@@ -133,15 +133,20 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -133,15 +133,20 @@ class ScoperExprVisitor(ScoperVisitor):
self.visit_function_call(init, [ftype.inner_type, *arguments]) self.visit_function_call(init, [ftype.inner_type, *arguments])
return ftype.inner_type return ftype.inner_type
assert isinstance(ftype, CallableInstanceType) # assert isinstance(ftype, CallableInstanceType) TODO
if not isinstance(ftype, CallableInstanceType):
return TypeVariable()
for i, (a, b) in enumerate(zip_longest(ftype.parameters, arguments)): for i, (a, b) in enumerate(zip_longest(ftype.parameters, arguments)):
if b is None: if b is None:
if i >= ftype.optional_at: if i >= ftype.optional_at:
continue continue
raise ArgumentCountMismatchError(ftype, arguments) raise ArgumentCountMismatchError(ftype, arguments)
if a is None and ftype.is_variadic: if a is None:
break if ftype.is_variadic:
break
raise ArgumentCountMismatchError(ftype, arguments)
if not a.try_assign(b): if not a.try_assign(b):
raise TypeMismatchError(a, b, TypeMismatchKind.DIFFERENT_TYPE) raise TypeMismatchError(a, b, TypeMismatchKind.DIFFERENT_TYPE)
...@@ -155,8 +160,10 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -155,8 +160,10 @@ class ScoperExprVisitor(ScoperVisitor):
vis = ScoperBlockVisitor(scope) vis = ScoperBlockVisitor(scope)
for stmt in ftype.block_data.node.body: for stmt in ftype.block_data.node.body:
vis.visit(stmt) vis.visit(stmt)
if not getattr(scope, "has_return", False): if not getattr(scope.function, "has_return", False):
vis.visit(ast.Return()) stmt = ast.Return()
ftype.block_data.node.body.append(stmt)
vis.visit(stmt)
#ftype.generic_parent.cache_instance(ftype) #ftype.generic_parent.cache_instance(ftype)
return ftype.return_type.resolve() return ftype.return_type.resolve()
# if isinstance(ftype, TypeType):# and isinstance(ftype.type_object, UserType): # if isinstance(ftype, TypeType):# and isinstance(ftype.type_object, UserType):
...@@ -226,7 +233,11 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -226,7 +233,11 @@ class ScoperExprVisitor(ScoperVisitor):
ltype = ltype.deref() ltype = ltype.deref()
assert isinstance(ltype, ResolvedConcreteType) #assert isinstance(ltype, ResolvedConcreteType) TODO?
if not isinstance(ltype, ResolvedConcreteType):
return TypeVariable()
# if mdecl := ltype.members.get(name): # if mdecl := ltype.members.get(name):
# attr = mdecl.type # attr = mdecl.type
# if getattr(attr, "is_python_func", False): # if getattr(attr, "is_python_func", False):
......
...@@ -15,7 +15,7 @@ from transpiler.phases.typing.scope import Scope, VarDecl, VarKind, ScopeKind ...@@ -15,7 +15,7 @@ from transpiler.phases.typing.scope import Scope, VarDecl, VarKind, ScopeKind
from transpiler.phases.typing.types import BaseType, BuiltinGenericType, BuiltinType, create_builtin_generic_type, \ from transpiler.phases.typing.types import BaseType, BuiltinGenericType, BuiltinType, create_builtin_generic_type, \
create_builtin_type, ConcreteType, GenericInstanceType, TypeListType, TypeTupleType, GenericParameter, \ create_builtin_type, ConcreteType, GenericInstanceType, TypeListType, TypeTupleType, GenericParameter, \
GenericParameterKind, TypeVariable, ResolvedConcreteType, MemberDef, ClassTypeType, CallableInstanceType, \ GenericParameterKind, TypeVariable, ResolvedConcreteType, MemberDef, ClassTypeType, CallableInstanceType, \
MethodType, UniqueTypeMixin, GenericType, BlockData, TY_TASK MethodType, UniqueTypeMixin, GenericType, BlockData, TY_TASK, UserGenericType, UserType
from transpiler.phases.utils import NodeVisitorSeq from transpiler.phases.utils import NodeVisitorSeq
def visit_generic_item( def visit_generic_item(
...@@ -65,6 +65,8 @@ def visit_generic_item( ...@@ -65,6 +65,8 @@ def visit_generic_item(
assert b.try_assign(a) assert b.try_assign(a)
# todo # todo
new_output_type = instance_type() new_output_type = instance_type()
new_output_type.generic_parent = output_type
new_output_type.generic_args = args
visit_nongeneric(new_scope, new_output_type) visit_nongeneric(new_scope, new_output_type)
return new_output_type return new_output_type
output_type.constraints_ = [] output_type.constraints_ = []
...@@ -130,8 +132,14 @@ class StdlibVisitor(NodeVisitorSeq): ...@@ -130,8 +132,14 @@ class StdlibVisitor(NodeVisitorSeq):
assert isinstance(existing.type, ClassTypeType) assert isinstance(existing.type, ClassTypeType)
NewType = existing.type.inner_type NewType = existing.type.inner_type
else: else:
base_class = create_builtin_generic_type if node.type_params else create_builtin_type if node.type_params:
NewType = base_class(node.name) base_class, base_type = create_builtin_generic_type, (BuiltinGenericType if self.is_native else UserGenericType)
else:
base_class, base_type = create_builtin_type, (BuiltinType if self.is_native else UserType)
NewType = base_class(node.name,
"Builtin" if self.is_native else "User",
base_type
)
self.scope.vars[node.name] = VarDecl(VarKind.LOCAL, NewType.type_type(), is_item_decl=True) self.scope.vars[node.name] = VarDecl(VarKind.LOCAL, NewType.type_type(), is_item_decl=True)
def visit_nongeneric(scope: Scope, output: ResolvedConcreteType): def visit_nongeneric(scope: Scope, output: ResolvedConcreteType):
......
...@@ -233,6 +233,10 @@ class UniqueTypeMixin: ...@@ -233,6 +233,10 @@ class UniqueTypeMixin:
class BuiltinType(UniqueTypeMixin, ResolvedConcreteType): class BuiltinType(UniqueTypeMixin, ResolvedConcreteType):
pass pass
@dataclass(eq=False)
class UserType(BuiltinType):
pass
@dataclass @dataclass
class SpecialConstantType[T](ConcreteType): class SpecialConstantType[T](ConcreteType):
value: T value: T
...@@ -312,9 +316,9 @@ class GenericConstraint: ...@@ -312,9 +316,9 @@ class GenericConstraint:
right: ResolvedConcreteType right: ResolvedConcreteType
@dataclass(eq=False, init=False) @dataclass(eq=False)
class GenericType(BaseType): class GenericType(BaseType):
parameters: list[GenericParameter] parameters: list[GenericParameter] = field(default_factory=list, init=False)
instance_cache: dict[object, GenericInstanceType] = field(default_factory=dict, init=False) instance_cache: dict[object, GenericInstanceType] = field(default_factory=dict, init=False)
def constraints(self, args: list[ConcreteType]) -> list[GenericConstraint]: def constraints(self, args: list[ConcreteType]) -> list[GenericConstraint]:
...@@ -325,6 +329,7 @@ class GenericType(BaseType): ...@@ -325,6 +329,7 @@ class GenericType(BaseType):
raise NotImplementedError() raise NotImplementedError()
def instantiate(self, args: list[ConcreteType]) -> GenericInstanceType: def instantiate(self, args: list[ConcreteType]) -> GenericInstanceType:
__TB__ = f"instantiating {highlight(self.name())} with [{', '.join(map(highlight, map(str, args)))}]"
res = self._instantiate(args) res = self._instantiate(args)
res.generic_args = args res.generic_args = args
res.generic_parent = self res.generic_parent = self
...@@ -362,11 +367,15 @@ class BuiltinGenericType(UniqueTypeMixin, GenericType): ...@@ -362,11 +367,15 @@ class BuiltinGenericType(UniqueTypeMixin, GenericType):
return self.instantiate_(args) return self.instantiate_(args)
def create_builtin_type(name: str): @dataclass(eq=False, init=False)
class CreatedType(BuiltinType): class UserGenericType(BuiltinGenericType):
pass
def create_builtin_type(name: str, prefix="Builtin", base=BuiltinType):
class CreatedType(base):
def name(self): def name(self):
return name return name
CreatedType.__name__ = f"BuiltinType${name}" CreatedType.__name__ = f"{prefix}Type${name}"
res = CreatedType() res = CreatedType()
return res return res
...@@ -387,11 +396,11 @@ def unimpl(*args, **kwargs): ...@@ -387,11 +396,11 @@ def unimpl(*args, **kwargs):
raise NotImplementedError() raise NotImplementedError()
def create_builtin_generic_type(name: str): def create_builtin_generic_type(name: str, prefix="Builtin", base=BuiltinGenericType):
class CreatedType(BuiltinGenericType): class CreatedType(base):
def name(self): def name(self):
return name return name
CreatedType.__name__ = f"BuiltinGenericType${name}" CreatedType.__name__ = f"{prefix}GenericType${name}"
res = CreatedType() res = CreatedType()
return res return res
......
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