Commit 2e7eaeb0 authored by Tom Niget's avatar Tom Niget

Continue work on generics

parent a577191a
...@@ -5,23 +5,19 @@ ...@@ -5,23 +5,19 @@
#ifndef TYPON_BASEDEF_HPP #ifndef TYPON_BASEDEF_HPP
#define TYPON_BASEDEF_HPP #define TYPON_BASEDEF_HPP
template<typename Self> template <typename Self> class TyBuiltin {
class TyBuiltin { template <typename... Args> auto sync_wrapper(Args &&...args) {
template <typename... Args> return static_cast<Self *>(this)->sync(std::forward<Args>(args)...);
auto sync_wrapper(Args&&... args)
{
return static_cast<Self*>(this)->sync(std::forward<Args>(args)...);
} }
public: public:
template <typename... Args> template <typename... Args>
auto operator()(Args&&... args) -> decltype(sync_wrapper(std::forward<Args>(args)...)) auto operator()(Args &&...args)
{ -> decltype(sync_wrapper(std::forward<Args>(args)...)) {
return sync_wrapper(std::forward<Args>(args)...); return sync_wrapper(std::forward<Args>(args)...);
} }
}; };
/* /*
struct method {}; struct method {};
...@@ -50,9 +46,10 @@ auto dot_bind(Obj, Attr attr) { ...@@ -50,9 +46,10 @@ auto dot_bind(Obj, Attr attr) {
return attr; return attr;
} }
#define dot(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj, obj.NAME); }(OBJ) #define dot(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj, obj.NAME);
#define dotp(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj, obj->NAME); }(OBJ) }(OBJ) #define dotp(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj,
#define dots(OBJ, NAME) [](auto && obj) -> auto { return std::remove_reference<decltype(obj)>::type::py_type::NAME; }(OBJ) obj->NAME); }(OBJ) #define dots(OBJ, NAME) [](auto && obj) -> auto { return
std::remove_reference<decltype(obj)>::type::py_type::NAME; }(OBJ)
*/ */
......
This diff is collapsed.
...@@ -7,10 +7,36 @@ ...@@ -7,10 +7,36 @@
#include <ostream> #include <ostream>
#include "print.hpp" #include "../referencemodel.hpp"
#include "str.hpp"
template <> void print_to<bool>(const bool &x, std::ostream &s) { namespace typon {
s << (x ? "True" : "False"); using namespace referencemodel;
} template <typename _Base0 = object>
struct TyBool__oo : classtype<_Base0, TyBool__oo<>> {
static constexpr std::string_view name = "TyBool";
struct : method {
auto operator()(auto self) const {
return TyStr(self->value ? "True" : "False");
}
} static constexpr oo__str__oo{};
static constexpr auto oo__repr__oo = oo__str__oo;
struct Obj : value<TyBool__oo<>, Obj> {
bool value;
constexpr Obj(bool value = false) : value(value) {}
constexpr operator bool() const { return value; }
};
/*static constexpr Obj TRUE = Obj(true);
static constexpr Obj FALSE = Obj(false);*/
auto operator()(bool value) const { return Obj(value); }
};
static constexpr TyBool__oo<> TyBool{};
} // namespace typon
#endif // TYPON_BOOL_HPP #endif // TYPON_BOOL_HPP
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef TYPON_BYTES_H #ifndef TYPON_BYTES_H
#define TYPON_BYTES_H #define TYPON_BYTES_H
class TyStr; /*class TyStr;
class TyBytes : public std::string { class TyBytes : public std::string {
public: public:
...@@ -18,10 +18,35 @@ public: ...@@ -18,10 +18,35 @@ public:
template <class InputIterator> template <class InputIterator>
TyBytes(InputIterator first, InputIterator last) : std::string(first, last) {} TyBytes(InputIterator first, InputIterator last) : std::string(first, last) {}
//TyStr decode_inner(const std::string &encoding = "utf-8") const; // TyStr decode_inner(const std::string &encoding = "utf-8") const;
METHOD(TyStr, decode, (Self self, const std::string &encoding = "utf-8"), ;) METHOD(TyStr, decode, (Self self, const std::string &encoding = "utf-8"), ;)
};*/
namespace typon {
using namespace referencemodel;
template <typename _Base0 = object>
struct TyBytes__oo : classtype<_Base0, TyBytes__oo<>> {
static constexpr std::string_view name = "TyBytes";
struct : method {
auto operator()(auto self, auto other) const {
return Obj(dot(self, value) + dot(other, value));
}
} static constexpr oo__add__oo{};
struct Obj : value<TyBytes__oo<>, Obj> {
std::string value;
constexpr Obj() : value() {}
constexpr Obj(std::string value) : value(value) {}
operator std::string() const { return value; }
};
auto operator()(std::string value) const { return Obj(value); }
}; };
static constexpr TyBytes__oo<> TyBytes{};
#endif // TYPON_BYTES_H } // namespace typon
#endif // TYPON_BYTES_H
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#ifndef TYPON_DICT_HPP #ifndef TYPON_DICT_HPP
#define TYPON_DICT_HPP #define TYPON_DICT_HPP
#include <unordered_map>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <unordered_map>
/* /*
template <typename K, typename V> template <typename K, typename V>
...@@ -87,7 +87,7 @@ TyDict(std::initializer_list<std::pair<K, V>>) -> TyDict<K, V>;*/ ...@@ -87,7 +87,7 @@ TyDict(std::initializer_list<std::pair<K, V>>) -> TyDict<K, V>;*/
namespace typon { namespace typon {
template <typename K, typename V> class TyDict { /*template <typename K, typename V> class TyDict {
public: public:
TyDict(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {} TyDict(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {}
TyDict(std::unordered_map<K, V> &&m) TyDict(std::unordered_map<K, V> &&m)
...@@ -132,14 +132,87 @@ public: ...@@ -132,14 +132,87 @@ public:
private: private:
std::shared_ptr<std::unordered_map<K, V>> _m; std::shared_ptr<std::unordered_map<K, V>> _m;
};*/
} // namespace typon
/*namespace PYBIND11_NAMESPACE {
namespace detail {
template <typename K, typename V>
struct type_caster<typon::TyDict<K, V>>
: map_caster<typon::TyDict<K, V>, K, V> {};
} // namespace detail
} // namespace PYBIND11_NAMESPACE*/
namespace typon {
using namespace referencemodel;
template <typename _Base0 = object>
struct TyDict__oo : classtype<_Base0, TyDict__oo<>> {
struct : method {
template <typename Self> auto operator()(Self self) const {
std::stringstream s;
s << '{';
if (self->_m->size() > 0) {
s << repr(self->_m->begin()->first)->value;
s << ": ";
s << repr(self->_m->begin()->second)->value;
for (auto it = ++self->_m->begin(); it != self->_m->end(); it++) {
s << ", ";
s << repr(it->first)->value;
s << ": ";
s << repr(it->second)->value;
}
}
s << '}';
return typon::TyStr__oo<>::Obj(s.str());
}
} static constexpr 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>> {
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::unordered_map<K, V> &&m)
: _m(std::move(
std::make_shared<std::unordered_map<K, V>>(std::move(m)))) {}
Obj(std::initializer_list<std::pair<K, V>> &&m)
: _m(std::make_shared<std::unordered_map<K, V>>(std::move(m))) {}
Obj() : _m(std::make_shared<std::unordered_map<K, V>>()) {}
template <typename... Args>
Obj(Args &&...args)
: _m(std::make_shared<std::unordered_map<K, V>>(
std::forward<Args>(args)...)) {}
};
template <typename T> auto operator()(std::initializer_list<T> &&v) const {
return rc(Obj(std::move(v)));
}
template <typename... Args> auto operator()(Args &&...args) const {
return rc(Obj(std::forward<Args>(args)...));
}
}; };
} static constexpr TyDict__oo<> TyDict{};
} // namespace typon
/*template <typename T> auto dict(std::initializer_list<T> &&v) {
return typon::TyDict(std::move(v));
}*/
namespace PYBIND11_NAMESPACE { namespace PYBIND11_NAMESPACE {
namespace detail { namespace detail {
template <typename K, typename V> template <typename K, typename V>
struct type_caster<typon::TyDict<K, V>> : map_caster<typon::TyDict<K, V>, K, V> {}; struct type_caster<typon::TyDict__oo<>::Obj<K, V>>
}} : map_caster<typon::TyDict__oo<>::Obj<K, V>, K, V> {};
} // namespace detail
} // namespace PYBIND11_NAMESPACE
#endif // TYPON_DICT_HPP #endif // TYPON_DICT_HPP
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
struct TyException_s { struct TyException_s {
struct py_type { struct py_type {
TyStr message; TyStr__oo<>::Obj message;
}; };
auto operator()(const TyStr &message) const { auto operator()(const TyStr__oo<>::Obj &message) const {
return py_type{message}; return py_type{message};
} }
}; };
......
...@@ -5,110 +5,98 @@ ...@@ -5,110 +5,98 @@
#ifndef TYPON_INT_HPP #ifndef TYPON_INT_HPP
#define TYPON_INT_HPP #define TYPON_INT_HPP
#include <algorithm>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <algorithm>
using namespace std::literals; using namespace std::literals;
#include "bytes.hpp" #include "str.hpp"
#include "print.hpp"
#include "slice.hpp"
// #include <format> // #include <format>
#include <fmt/format.h> #include <fmt/format.h>
#include <pybind11/cast.h> #include <pybind11/cast.h>
namespace typon { namespace typon {
/*template <typename _Base0 = object> using namespace referencemodel;
class TyInt__oo : classtype<_Base0, Integer__oo<>> {
public: template <typename _Base0 = object>
struct TyInt__oo : classtype<_Base0, TyInt__oo<>> {
static constexpr std::string_view name = "TyInt";
struct : method { struct : method {
auto operator()(auto self, int value) const { auto operator()(auto self, auto other) const {
self->value = value; return Obj(dot(self, value) + dot(other, value));
} }
} static constexpr oo__init__oo {}; } static constexpr oo__add__oo{};
struct : method { struct : method {
auto operator()(auto self, auto other) const { auto operator()(auto self, auto other) const {
return Integer(dot(self, value) + dot(other, value)); return Obj(dot(self, value) - dot(other, value));
} }
} static constexpr oo__add__oo {}; } static constexpr oo__sub__oo{};
auto operator () (int value) const { struct : method {
struct Obj : instance<Integer__oo<>, Obj> { auto operator()(auto self, auto other) const {
int value; return Obj(dot(self, value) * dot(other, value));
};
auto obj = rc(Obj{});
dot(obj, oo__init__oo)(value);
return obj;
} }
} static constexpr oo__mul__oo{};
struct : method {
auto operator()(auto self, auto other) const {
return Obj(dot(self, value) & dot(other, value));
}
} static constexpr oo__and__oo{};
struct : method {
auto operator()(auto self) const { return Obj(-dot(self, value)); }
} static constexpr oo__neg__oo{};
constexpr TyInt(int value) : value(value) {} struct : method {
constexpr TyInt() : value(0) {} auto operator()(auto self, auto other) const {
return dot(self, value) < dot(other, value);
operator int() const { return value; } }
} static constexpr oo__lt__oo{};
// operators
template <typename T> TyInt operator+(T x) const { return value + x; }
template <typename T> TyInt operator-(T x) const { return value - x; }
template <typename T> TyInt operator*(T x) const { return value * x; }
template <typename T> TyInt operator/(T x) const { return value / x; }
template <typename T> TyInt operator%(T x) const { return value % x; }
template <typename T> TyInt operator&(T x) const { return value & x; }
template <typename T> TyInt operator|(T x) const { return value | x; }
template <typename T> TyInt operator^(T x) const { return value ^ x; }
template <typename T> TyInt operator<<(T x) const { return value << x; }
template <typename T> TyInt operator>>(T x) const { return value >> x; }
template <typename T> TyInt operator&&(T x) const { return value && x; }
template <typename T> TyInt operator||(T x) const { return value || x; }
template <typename T> TyInt operator==(T x) const { return value == x; }
template <typename T> TyInt operator<(T x) const { return value < x; }
TyInt operator-() const { return -value; }
private: struct : method {
int value; auto operator()(auto self, auto other) const {
};*/ return dot(self, value) > dot(other, value);
using namespace referencemodel; }
template <typename _Base0 = object> } static constexpr oo__gt__oo{};
struct Integer__oo : classtype<_Base0, Integer__oo<>> {
static constexpr std::string_view name = "Integer";
struct : method { struct : method {
auto operator()(auto self, int value) const { auto operator()(auto self, auto other) const {
self->value = value; return TyInt(dot(self, value) % dot(other, value));
} }
} static constexpr oo__init__oo {}; } static constexpr oo__mod__oo{};
struct : method { struct : method {
auto operator()(auto self, auto other) const { auto operator()(auto self, auto other) const {
return TyInt(dot(self, value) + dot(other, value)); return dot(self, value) >= dot(other, value);
} }
} static constexpr oo__add__oo {}; } static constexpr oo__ge__oo{};
struct Obj : value<Integer__oo<>, Obj> { struct : method {
auto operator()(auto self) const {
return TyStr__oo<>::Obj(std::to_string(self->value));
}
} static constexpr oo__str__oo{};
static constexpr auto oo__repr__oo = oo__str__oo;
struct Obj : value<TyInt__oo<>, Obj> {
int value; int value;
Obj(int value=0) : value(value) {} Obj(int value = 0) : value(value) {}
operator int() const { return value; } operator int() const { return value; }
}; };
auto operator () (int value) const { auto operator()(int value) const { return Obj(value); }
auto obj = rc(Obj{}); };
dot(obj, oo__init__oo)(value); static constexpr TyInt__oo<> TyInt{};
return obj;
}
};
static constexpr Integer__oo<> TyInt {};
} } // namespace typon
inline auto operator ""_pi(unsigned long long int v) noexcept { inline auto operator""_pi(unsigned long long int v) noexcept {
return typon::TyInt(v); return typon::TyInt(v);
} }
...@@ -120,15 +108,8 @@ template <> struct std::hash<decltype(0_pi)> { ...@@ -120,15 +108,8 @@ template <> struct std::hash<decltype(0_pi)> {
namespace PYBIND11_NAMESPACE { namespace PYBIND11_NAMESPACE {
namespace detail { namespace detail {
template<> template <> struct type_caster<decltype(0_pi)> : type_caster<int> {};
struct type_caster<decltype(0_pi)> } // namespace detail
: type_caster<int> {}; } // namespace PYBIND11_NAMESPACE
}}
template <> void repr_to(const decltype(0_pi) &x, std::ostream &s) {
s << x;
}
template <> void print_to<decltype(0_pi)>(const decltype(0_pi) &x, std::ostream &s) { s << x; }
#endif // TYPON_INT_HPP #endif // TYPON_INT_HPP
...@@ -8,14 +8,90 @@ ...@@ -8,14 +8,90 @@
#include <algorithm> #include <algorithm>
#include <ostream> #include <ostream>
#include <vector> #include <vector>
//#include <nanobind/stl/detail/nb_list.h> // #include <nanobind/stl/detail/nb_list.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
namespace typon { namespace typon {
using namespace referencemodel;
template <typename _Base0 = object>
struct TyList__oo : classtype<_Base0, TyList__oo<>> {
template <typename T> class TyList { struct : method {
public: template <typename Self> auto operator()(Self self) const {
return TyList__oo<>{}(self->_v);
}
} static constexpr copy{};
struct : method {
template <typename Self, typename Other>
auto operator()(Self self, Other other) const {
self->_v.reserve(self->_v.size() + other.size());
self->_v.insert(self->_v.end(), other.begin(), other.end());
}
} static constexpr extend{};
struct : method {
template <typename Self, typename Other>
auto operator()(Self self, Other other) const {
auto result = TyList__oo<>{}(self->_v);
dot(result, extend)(other);
return result;
}
} static constexpr oo__add__oo{};
struct : method {
template <typename Self, typename Other>
auto operator()(Self self, Other other) const {
auto result = TyList__oo<>{}(self->_v);
result->_v->reserve(result->_v->size() * other);
for (int i = 0; i < other - 1; i++) {
dot(result, extend)(self);
}
return result;
}
} static constexpr oo__mul__oo{};
struct : method {
template <typename Self> auto operator()(Self self) const {
std::stringstream s;
s << '[';
if (self->_v->size() > 0) {
s << repr(self->_v->operator[](0))->value;
for (size_t i = 1; i < self->_v->size(); i++) {
s << ", ";
s << repr(self->_v->operator[](i))->value;
}
}
s << ']';
return typon::TyStr__oo<>::Obj(s.str());
}
} static constexpr oo__repr__oo{};
static constexpr auto oo__str__oo = oo__repr__oo;
template <typename T> struct Obj : instance<TyList__oo<>, Obj<T>> {
using value_type = T; using value_type = T;
std::shared_ptr<std::vector<T>> _v;
Obj(std::shared_ptr<std::vector<T>> &&v) : _v(std::move(v)) {}
Obj(std::vector<T> &&v)
: _v(std::move(std::make_shared<std::vector<T>>(std::move(v)))) {}
Obj(std::initializer_list<T> &&v)
: _v(std::make_shared<std::vector<T>>(std::move(v))) {}
Obj() : _v(std::make_shared<std::vector<T>>()) {}
};
template <typename T> auto operator()(std::initializer_list<T> &&v) const {
return rc(Obj(std::move(v)));
}
template <typename... Args> auto operator()(Args &&...args) const {
return rc(Obj(std::forward<Args>(args)...));
}
/*
TyList(std::shared_ptr<std::vector<T>> &&v) : _v(std::move(v)) {} TyList(std::shared_ptr<std::vector<T>> &&v) : _v(std::move(v)) {}
TyList(std::vector<T> &&v) TyList(std::vector<T> &&v)
: _v(std::move(std::make_shared<std::vector<T>>(std::move(v)))) {} : _v(std::move(std::make_shared<std::vector<T>>(std::move(v)))) {}
...@@ -41,7 +117,7 @@ public: ...@@ -41,7 +117,7 @@ public:
void push_back(const T &value) { _v->push_back(value); } void push_back(const T &value) { _v->push_back(value); }
void clear() { _v->clear(); } void clear() { _v->clear(); }*/
/*operator std::vector<T>() const { /*operator std::vector<T>() const {
return std::vector<T>(this->begin(), this->end()); return std::vector<T>(this->begin(), this->end());
...@@ -51,7 +127,7 @@ public: ...@@ -51,7 +127,7 @@ public:
return *reinterpret_cast<std::vector<T> *>(this); return *reinterpret_cast<std::vector<T> *>(this);
}*/ }*/
constexpr const T &operator[](size_t i) const { return _v->operator[](i); } /*constexpr const T &operator[](size_t i) const { return _v->operator[](i); }
constexpr T &operator[](size_t i) { return _v->operator[](i); } constexpr T &operator[](size_t i) { return _v->operator[](i); }
size_t py_len() const { return _v->size(); } size_t py_len() const { return _v->size(); }
...@@ -68,44 +144,24 @@ public: ...@@ -68,44 +144,24 @@ public:
s << ']'; s << ']';
} }
void py_print(std::ostream &s) const { py_repr(s); } void py_print(std::ostream &s) const { py_repr(s); }*/
TyList<T> operator+(const TyList<T> &other) const {
std::vector<T> v;
v.reserve(_v->size() + other._v->size());
v.insert(v.end(), _v->begin(), _v->end());
v.insert(v.end(), other._v->begin(), other._v->end());
return TyList<T>(std::move(v));
}
TyList<T> operator*(size_t n) const {
TyList<T> v{};
v._v->reserve(this->_v->size() * n);
for (size_t i = 0; i < n; i++) {
v._v->insert(v._v->end(), this->_v->begin(), this->_v->end());
}
return v;
}
private:
std::shared_ptr<std::vector<T>> _v;
}; };
static constexpr TyList__oo<> TyList{};
} // namespace typon
template <typename T> auto list(std::initializer_list<T> &&v) {
return typon::TyList(std::move(v));
}
template <typename T> typon::TyList<T> list(std::initializer_list<T> &&v) {
return typon::TyList<T>(std::move(v));
} }
namespace PYBIND11_NAMESPACE { namespace PYBIND11_NAMESPACE {
namespace detail { namespace detail {
template <typename Type> template <typename Type>
struct type_caster<typon::TyList<Type>> : list_caster<typon::TyList<Type>, Type> {}; struct type_caster<typon::TyList__oo<>::Obj<Type>>
}} : list_caster<typon::TyList__oo<>::Obj<Type>, Type> {};
} // namespace detail
} // namespace PYBIND11_NAMESPACE
/*NAMESPACE_BEGIN(NB_NAMESPACE) /*NAMESPACE_BEGIN(NB_NAMESPACE)
NAMESPACE_BEGIN(detail) NAMESPACE_BEGIN(detail)
......
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
#ifndef TYPON_PRINT_HPP #ifndef TYPON_PRINT_HPP
#define TYPON_PRINT_HPP #define TYPON_PRINT_HPP
#include <functional>
#include <iostream> #include <iostream>
#include <ostream> #include <ostream>
#include <functional>
#include <typon/typon.hpp> #include <typon/typon.hpp>
template <typename T> /*template <typename T>
concept Streamable = requires(const T &x, std::ostream &s) { concept Streamable = requires(const T &x, std::ostream &s) {
{ s << x } -> std::same_as<std::ostream &>; { s << x } -> std::same_as<std::ostream &>;
}; };
...@@ -42,14 +42,14 @@ concept Printable = requires(const T &x, std::ostream &s) { ...@@ -42,14 +42,14 @@ concept Printable = requires(const T &x, std::ostream &s) {
template <typename T> template <typename T>
concept Reprable = requires(const T &x, std::ostream &s) { concept Reprable = requires(const T &x, std::ostream &s) {
{ repr_to(x, s) } -> std::same_as<void>; { repr_to(x, s) } -> std::same_as<void>;
}; };*/
template <typename T> template <typename T>
concept FunctionPointer = concept FunctionPointer =
std::is_function_v<T> or std::is_member_function_pointer_v<T> or std::is_function_v<T> or std::is_member_function_pointer_v<T> or
std::is_function_v<std::remove_pointer_t<T>>; std::is_function_v<std::remove_pointer_t<T>>;
template <Streamable T> /*template <Streamable T>
requires(FunctionPointer<T>) requires(FunctionPointer<T>)
void repr_to(const T &x, std::ostream &s) { void repr_to(const T &x, std::ostream &s) {
s << "<function at 0x" << std::hex << (size_t)x << std::dec << ">"; s << "<function at 0x" << std::hex << (size_t)x << std::dec << ">";
...@@ -57,7 +57,8 @@ void repr_to(const T &x, std::ostream &s) { ...@@ -57,7 +57,8 @@ void repr_to(const T &x, std::ostream &s) {
template <typename T> template <typename T>
void repr_to(const std::function<T> &x, std::ostream &s) { void repr_to(const std::function<T> &x, std::ostream &s) {
s << "<function at 0x" << std::hex << (size_t)x.template target<T*>() << std::dec s << "<function at 0x" << std::hex << (size_t)x.template target<T*>() <<
std::dec
<< ">"; << ">";
} }
...@@ -75,7 +76,7 @@ void print_to(const std::shared_ptr<T> &x, std::ostream &s) { ...@@ -75,7 +76,7 @@ void print_to(const std::shared_ptr<T> &x, std::ostream &s) {
template <Reprable T> template <Reprable T>
void repr_to(const std::shared_ptr<T> &x, std::ostream &s) { void repr_to(const std::shared_ptr<T> &x, std::ostream &s) {
repr_to(*x, s); repr_to(*x, s);
} }*/
/* /*
template <Printable T, Printable... Args> template <Printable T, Printable... Args>
...@@ -86,18 +87,19 @@ typon::Task<void> print(T const &head, Args const &...args) { ...@@ -86,18 +87,19 @@ typon::Task<void> print(T const &head, Args const &...args) {
}*/ }*/
struct { struct {
typon::TyNone operator()() { std::cout << '\n'; return {}; } typon::TyNone operator()() {
std::cout << '\n';
return {};
}
template <Printable T, Printable... Args> template <typename T, typename... Args>
typon::TyNone operator()(T const &head, Args const &...args) { typon::TyNone operator()(T const &head, Args const &...args) {
print_to(head, std::cout); std::cout << str(head)->value;
(((std::cout << ' '), print_to(args, std::cout)), ...); (((std::cout << ' '), (std::cout << str(args)->value)), ...);
std::cout << '\n'; std::cout << '\n';
return {}; return {};
} }
} print; } print;
// typon::Task<void> print() { std::cout << '\n'; co_return; } // typon::Task<void> print() { std::cout << '\n'; co_return; }
#endif // TYPON_PRINT_HPP #endif // TYPON_PRINT_HPP
...@@ -12,30 +12,30 @@ namespace view = std::views; ...@@ -12,30 +12,30 @@ namespace view = std::views;
#include <python/basedef.hpp> #include <python/basedef.hpp>
auto stride = [](int n) { auto stride = [](int n) {
return [s = -1, n](auto const&) mutable { s = (s + 1) % n; return !s; }; return [s = -1, n](auto const &) mutable {
s = (s + 1) % n;
return !s;
};
}; };
// todo: proper range support // todo: proper range support
struct range_s : TyBuiltin<range_s> struct range_s : TyBuiltin<range_s> {
{
auto sync(int start, int stop, int step = 1) { auto sync(int start, int stop, int step = 1) {
// https://www.modernescpp.com/index.php/c-20-pythons-map-function/ // https://www.modernescpp.com/index.php/c-20-pythons-map-function/
if(step == 0) { if (step == 0) {
throw std::invalid_argument("Step cannot be 0"); throw std::invalid_argument("Step cannot be 0");
} }
auto Step = start < stop ? step : -step; auto Step = start < stop ? step : -step;
auto Begin = std::min(start, stop); auto Begin = std::min(start, stop);
auto End = Step < 0 ? Begin : std::max(start, stop); auto End = Step < 0 ? Begin : std::max(start, stop);
return view::iota(Begin, End) return view::iota(Begin, End) | view::filter(stride(std::abs(Step))) |
| view::filter(stride(std::abs(Step))) view::transform([start, stop](std::size_t i) {
| view::transform([start, stop](std::size_t i){
return start < stop ? i : stop - (i - start); return start < stop ? i : stop - (i - start);
}); });
} }
auto sync(int stop) { return sync(0, stop); } auto sync(int stop) { return sync(0, stop); }
} range; } range;
#endif // TYPON_RANGE_HPP #endif // TYPON_RANGE_HPP
...@@ -71,7 +71,7 @@ public: ...@@ -71,7 +71,7 @@ public:
} }
}; };
} } // namespace typon
template <typename T> typon::TySet<T> set(std::initializer_list<T> &&s) { template <typename T> typon::TySet<T> set(std::initializer_list<T> &&s) {
return typon::TySet<T>(std::move(s)); return typon::TySet<T>(std::move(s));
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
#ifndef TYPON_SLICE_HPP #ifndef TYPON_SLICE_HPP
#define TYPON_SLICE_HPP #define TYPON_SLICE_HPP
#include <optional>
#include <utility>
#include <Python.h> #include <Python.h>
#include <optional>
#include <stdint.h> #include <stdint.h>
#include <utility>
struct TySlice { struct TySlice {
TySlice() = default; TySlice() = default;
...@@ -17,7 +17,9 @@ struct TySlice { ...@@ -17,7 +17,9 @@ struct TySlice {
TySlice &operator=(const TySlice &) = default; TySlice &operator=(const TySlice &) = default;
TySlice &operator=(TySlice &&) = default; TySlice &operator=(TySlice &&) = default;
TySlice(std::optional<ssize_t> start, std::optional<ssize_t> stop, std::optional<ssize_t> step) : start(start), stop(stop), step(step) { TySlice(std::optional<ssize_t> start, std::optional<ssize_t> stop,
std::optional<ssize_t> step)
: start(start), stop(stop), step(step) {
if (step == 0) { if (step == 0) {
throw std::runtime_error("slice step cannot be zero"); throw std::runtime_error("slice step cannot be zero");
} }
...@@ -52,7 +54,8 @@ struct TySlice { ...@@ -52,7 +54,8 @@ struct TySlice {
res.stop = this->stop.value(); res.stop = this->stop.value();
} }
auto len = PySlice_AdjustIndices(seq_length, &res.start, &res.stop, res.step); auto len =
PySlice_AdjustIndices(seq_length, &res.start, &res.stop, res.step);
return {len, res}; return {len, res};
} }
......
...@@ -5,20 +5,19 @@ ...@@ -5,20 +5,19 @@
#ifndef TYPON_STR_HPP #ifndef TYPON_STR_HPP
#define TYPON_STR_HPP #define TYPON_STR_HPP
#include <algorithm>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <algorithm>
using namespace std::literals; using namespace std::literals;
#include "bytes.hpp" #include "bytes.hpp"
#include "print.hpp"
#include "slice.hpp" #include "slice.hpp"
// #include <format> // #include <format>
#include <fmt/format.h> #include <fmt/format.h>
#include <pybind11/cast.h> #include <pybind11/cast.h>
class TyStr : public std::string { /*class TyStr : public std::string {
public: public:
TyStr() : std::string() {} TyStr() : std::string() {}
TyStr(const std::string &s) : std::string(s) {} TyStr(const std::string &s) : std::string(s) {}
...@@ -108,8 +107,8 @@ inline constexpr TyStr operator""_ps(const char *s, size_t len) noexcept { ...@@ -108,8 +107,8 @@ inline constexpr TyStr operator""_ps(const char *s, size_t len) noexcept {
} }
template<typename Self> template<typename Self>
TyStr TyBytes::decode_s::operator()(Self self, const std::string &encoding) const { TyStr TyBytes::decode_s::operator()(Self self, const std::string &encoding)
return TyStr(self.begin(), self.end()); const { return TyStr(self.begin(), self.end());
} }
template <typename T> TyStr str(const T &x) { template <typename T> TyStr str(const T &x) {
...@@ -150,6 +149,84 @@ struct { ...@@ -150,6 +149,84 @@ struct {
std::getline(std::cin, input); std::getline(std::cin, input);
return input; return input;
} }
} input; } input;*/
namespace typon {
using namespace referencemodel;
template <typename _Base0 = object>
struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
static constexpr std::string_view name = "TyStr";
struct : method {
auto operator()(auto self, auto other) const {
return Obj(dot(self, value) + dot(other, value));
}
} static constexpr oo__add__oo{};
struct : method {
auto operator()(auto self) const { return Obj(self->value); }
} static constexpr oo__str__oo{};
struct : method {
auto operator()(auto self) const {
return Obj(fmt::format("\"{}\"", self->value));
}
} static constexpr oo__repr__oo{};
struct Obj : value<TyStr__oo<>, Obj> {
std::string value;
constexpr Obj() : value() {}
constexpr Obj(std::string value) : value(value) {}
operator std::string() const { return value; }
};
auto operator()(std::string value) const { return Obj(value); }
};
static constexpr TyStr__oo<> TyStr{};
} // namespace typon
inline constexpr auto operator""_ps(const char *s, size_t len) noexcept {
return typon::TyStr__oo<>::Obj(std::string(s, len));
}
/*template <typename T> auto str(const T &x) { return dot(x, oo__str__oo)(); }
template <typename T>
concept NoStr = not requires(T x) { dot(x, oo__str__oo)(); };
template <NoStr T> auto str(const T &x) {
std::stringstream s;
s << x;
return typon::TyStr__oo<>::Obj(s.str());
}
*/
template <typename T>
concept HasStr = requires(T x) { dot(x, oo__str__oo)(); };
template <typename T>
concept HasRepr = requires(T x) { dot(x, oo__repr__oo)(); };
template <typename T> auto str(const T &x) {
if constexpr (HasStr<T>) {
return dot(x, oo__str__oo)();
} else {
std::stringstream s;
s << x;
return typon::TyStr__oo<>::Obj(s.str());
}
}
template <typename T> auto repr(const T &x) {
if constexpr (HasRepr<T>) {
return dot(x, oo__repr__oo)();
} else {
std::stringstream s;
s << x;
return typon::TyStr__oo<>::Obj(s.str());
}
}
#endif // TYPON_STR_HPP #endif // TYPON_STR_HPP
...@@ -74,16 +74,14 @@ struct hashlib_t { ...@@ -74,16 +74,14 @@ struct hashlib_t {
auto ctx = tyObj<SHA256_CTX>(); auto ctx = tyObj<SHA256_CTX>();
SHA256_Init(ctx.get()); SHA256_Init(ctx.get());
return tyObj<_Hash_s>(ctx, (openssl_update)SHA256_Update, return tyObj<_Hash_s>(ctx, (openssl_update)SHA256_Update,
(openssl_final)SHA256_Final, (openssl_final)SHA256_Final, SHA256_DIGEST_LENGTH);
SHA256_DIGEST_LENGTH);
}) })
FUNCTION(auto, sha512, (), { FUNCTION(auto, sha512, (), {
auto ctx = tyObj<SHA512_CTX>(); auto ctx = tyObj<SHA512_CTX>();
SHA512_Init(ctx.get()); SHA512_Init(ctx.get());
return tyObj<_Hash_s>(ctx, (openssl_update)SHA512_Update, return tyObj<_Hash_s>(ctx, (openssl_update)SHA512_Update,
(openssl_final)SHA512_Final, (openssl_final)SHA512_Final, SHA512_DIGEST_LENGTH);
SHA512_DIGEST_LENGTH);
}) })
} all; } all;
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
namespace py_json { namespace py_json {
struct json_t { struct json_t {
FUNCTION(template <typename T> typon::Task<void>, dump, (const T &x, typon::PyFile &fp), { FUNCTION(template <typename T> typon::Task<void>, dump,
(const T &x, typon::PyFile &fp), {
std::stringstream ss; std::stringstream ss;
repr_to(x, ss); repr_to(x, ss);
co_await dotp(fp, write)(ss.str()); co_await dotp(fp, write)(ss.str());
......
...@@ -21,8 +21,7 @@ int no_special(const struct dirent *d) { ...@@ -21,8 +21,7 @@ int no_special(const struct dirent *d) {
namespace py_os { namespace py_os {
struct os_t { struct os_t {
FUNCTION( FUNCTION(auto, fsdecode, (std::string s), { return s; })
auto, fsdecode, (std::string s), { return s; })
struct Stat_Result_s { struct Stat_Result_s {
struct py_type { struct py_type {
...@@ -64,8 +63,9 @@ struct os_t { ...@@ -64,8 +63,9 @@ struct os_t {
}) })
METHOD(auto, begin, (Self self), { return *self; }) METHOD(auto, begin, (Self self), { return *self; })
METHOD(auto, end, (Self self), METHOD(auto, end, (Self self), {
{ return py_type(self->basepath, self->namelist, self->n, self->n); }) return py_type(self->basepath, self->namelist, self->n, self->n);
})
auto operator*() { auto operator*() {
auto name = TyStr(this->namelist[this->current]->d_name); auto name = TyStr(this->namelist[this->current]->d_name);
...@@ -95,29 +95,23 @@ struct os_t { ...@@ -95,29 +95,23 @@ struct os_t {
}; };
} _Scandiriterator; } _Scandiriterator;
FUNCTION(typon::Task<TyObj<Stat_Result_s>>, stat, (const TyStr &path), FUNCTION(typon::Task<TyObj<Stat_Result_s>>, stat, (const TyStr &path), {
{
const char *path_c = path.c_str(); const char *path_c = path.c_str();
struct statx statxbuf; struct statx statxbuf;
if (int err = co_await typon::io::statx(AT_FDCWD, path_c, 0, if (int err = co_await typon::io::statx(AT_FDCWD, path_c, 0, STATX_SIZE,
STATX_SIZE, &statxbuf)) { &statxbuf)) {
system_error(-err, "statx()"); system_error(-err, "statx()");
} }
co_return TyObj<Stat_Result_s>(new Stat_Result_s::py_type{ co_return TyObj<Stat_Result_s>(new Stat_Result_s::py_type{
statxbuf.stx_mode, statxbuf.stx_mode, statxbuf.stx_ino,
statxbuf.stx_ino,
makedev(statxbuf.stx_dev_major, statxbuf.stx_dev_minor), makedev(statxbuf.stx_dev_major, statxbuf.stx_dev_minor),
statxbuf.stx_nlink, statxbuf.stx_nlink, statxbuf.stx_uid, statxbuf.stx_gid,
statxbuf.stx_uid,
statxbuf.stx_gid,
statxbuf.stx_size, statxbuf.stx_size,
statxbuf.stx_atime.tv_sec + statxbuf.stx_atime.tv_nsec / 1e9f, statxbuf.stx_atime.tv_sec + statxbuf.stx_atime.tv_nsec / 1e9f,
statxbuf.stx_mtime.tv_sec + statxbuf.stx_mtime.tv_nsec / 1e9f, statxbuf.stx_mtime.tv_sec + statxbuf.stx_mtime.tv_nsec / 1e9f,
statxbuf.stx_ctime.tv_sec + statxbuf.stx_ctime.tv_nsec / 1e9f, statxbuf.stx_ctime.tv_sec + statxbuf.stx_ctime.tv_nsec / 1e9f,
statxbuf.stx_blocks, statxbuf.stx_blocks, statxbuf.stx_blksize,
statxbuf.stx_blksize, makedev(statxbuf.stx_rdev_major, statxbuf.stx_rdev_minor), 0,
makedev(statxbuf.stx_rdev_major, statxbuf.stx_rdev_minor),
0,
statxbuf.stx_btime.tv_sec + statxbuf.stx_btime.tv_nsec / 1e9}); statxbuf.stx_btime.tv_sec + statxbuf.stx_btime.tv_nsec / 1e9});
}) })
...@@ -146,8 +140,8 @@ auto &get_all() { return all; } ...@@ -146,8 +140,8 @@ auto &get_all() { return all; }
} // namespace py_os } // namespace py_os
namespace typon { namespace typon {
using PyStat_Result = TyObj<py_os::os_t::Stat_Result_s>; using PyStat_Result = TyObj<py_os::os_t::Stat_Result_s>;
using Py_Scandiriterator = TyObj<py_os::os_t::_Scandiriterator_s>; using Py_Scandiriterator = TyObj<py_os::os_t::_Scandiriterator_s>;
} } // namespace typon
#endif // TYPON_OS_HPP #endif // TYPON_OS_HPP
This diff is collapsed.
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
#define TYPON_SOCKET_HPP #define TYPON_SOCKET_HPP
#include "builtins.hpp" #include "builtins.hpp"
#include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h>
#include <tuple> #include <tuple>
namespace py_socket { namespace py_socket {
...@@ -25,12 +25,14 @@ struct socket_t { ...@@ -25,12 +25,14 @@ struct socket_t {
struct socket_s { struct socket_s {
struct py_type { struct py_type {
METHOD(typon::Task<std::tuple<TyObj<py_type> COMMA() std::string>>, accept, (Self self), { METHOD(typon::Task<std::tuple<TyObj<py_type> COMMA() std::string>>,
accept, (Self self), {
int connfd = co_await typon::io::accept(self->fd, NULL, NULL); int connfd = co_await typon::io::accept(self->fd, NULL, NULL);
if (connfd < 0) { if (connfd < 0) {
system_error(-connfd, "accept()"); system_error(-connfd, "accept()");
} }
co_return std::make_tuple(tyObj<py_type>(connfd), std::string("")); // TODO co_return std::make_tuple(tyObj<py_type>(connfd),
std::string("")); // TODO
}) })
METHOD(typon::Task<void>, close, (Self self), METHOD(typon::Task<void>, close, (Self self),
...@@ -43,20 +45,24 @@ struct socket_t { ...@@ -43,20 +45,24 @@ struct socket_t {
} }
}) })
METHOD(void, setsockopt, (Self self, int level, int optname, int optval), { METHOD(void, setsockopt, (Self self, int level, int optname, int optval),
if (::setsockopt(self->fd, level, optname, &optval, sizeof(int)) < 0) { {
if (::setsockopt(self->fd, level, optname, &optval,
sizeof(int)) < 0) {
system_error(errno, "setsockopt()"); system_error(errno, "setsockopt()");
} }
}) })
METHOD(void, bind, (Self self, std::tuple<std::string COMMA() int> address), { METHOD(void, bind,
(Self self, std::tuple<std::string COMMA() int> address), {
auto [host, port] = address; auto [host, port] = address;
sockaddr_in6 addr; sockaddr_in6 addr;
std::memset(&addr, 0, sizeof(addr)); std::memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6; addr.sin6_family = AF_INET6;
addr.sin6_port = htons(port); addr.sin6_port = htons(port);
addr.sin6_addr = in6addr_any; addr.sin6_addr = in6addr_any;
if (::bind(self->fd, (const sockaddr *)&addr, sizeof(addr)) < 0) { if (::bind(self->fd, (const sockaddr *)&addr, sizeof(addr)) <
0) {
system_error(errno, "bind()"); system_error(errno, "bind()");
} }
}) })
...@@ -77,8 +83,7 @@ struct socket_t { ...@@ -77,8 +83,7 @@ struct socket_t {
py_type(int fd = -1) : fd(fd) {} py_type(int fd = -1) : fd(fd) {}
py_type(const py_type &other) py_type(const py_type &other) : fd(other.fd) {}
: fd(other.fd) {}
int fd; int fd;
}; };
...@@ -92,7 +97,10 @@ struct socket_t { ...@@ -92,7 +97,10 @@ struct socket_t {
} }
} socket; } socket;
FUNCTION(auto, getaddrinfo, (std::string host, int port, int family=0, int type_=0, int proto=0, int flags=0), { FUNCTION(auto, getaddrinfo,
(std::string host, int port, int family = 0, int type_ = 0,
int proto = 0, int flags = 0),
{
addrinfo hints; addrinfo hints;
std::memset(&hints, 0, sizeof(hints)); std::memset(&hints, 0, sizeof(hints));
hints.ai_family = family; hints.ai_family = family;
...@@ -102,7 +110,9 @@ struct socket_t { ...@@ -102,7 +110,9 @@ struct socket_t {
addrinfo *res; addrinfo *res;
// convert port to string // convert port to string
std::string port_str = std::to_string(port); std::string port_str = std::to_string(port);
if (int err = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &res); err != 0) { if (int err = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints,
&res);
err != 0) {
system_error(err, "getaddrinfo()"); system_error(err, "getaddrinfo()");
} }
return res; return res;
......
...@@ -5,24 +5,20 @@ ...@@ -5,24 +5,20 @@
#ifndef TYPON_SYS_HPP #ifndef TYPON_SYS_HPP
#define TYPON_SYS_HPP #define TYPON_SYS_HPP
#include <iostream>
#include "builtins.hpp" #include "builtins.hpp"
#include <iostream>
namespace py_sys { namespace py_sys {
struct sys_t { struct sys_t {
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<TyStr> argv; typon::TyList__oo<>::Obj<typon::TyStr__oo<>::Obj> argv;
FUNCTION(void, exit, (int code), { FUNCTION(void, exit, (int code), { std::exit(code); })
std::exit(code);
})
} all; } all;
auto& get_all() { auto &get_all() { return all; }
return all;
}
} // namespace py_sys } // namespace py_sys
#endif // TYPON_SYS_HPP #endif // TYPON_SYS_HPP
...@@ -42,15 +42,19 @@ if __name__ == "__main__": ...@@ -42,15 +42,19 @@ if __name__ == "__main__":
sum = 0 sum = 0
for i in range(15): for i in range(15):
sum = sum + i sum = sum + i
a = [n for n in range(10)] # a = [n for n in range(10)]
#b = [x for x in a if x % 2 == 0] # b = [x for x in a if x % 2 == 0]
#c = [y * y for y in b] #c = [y * y for y in b]
print("C++ " if is_cpp() else "Python", print("C++ " if is_cpp() else "Python",
"res=", 5, ".", True, [4, 5, 6], {7, 8, 9}, "res=", 5, ".", True, [4, 5, 6],
#[1, 2] + [3, 4], [5, 6] * 3, {1: 7, 9: 3}, #{7, 8, 9},
#0x55 & 7 == 5, # #[1, 2] + [3, 4], [5, 6] * 3,
#3j, {1: 7, 9: 3},
# 0x55 & 7 == 5,
# #3j,
sum, sum,
a) # # a,
# # b
)
print("Typon") print("Typon")
print() print()
...@@ -6,17 +6,12 @@ from socket import socket, SOCK_STREAM, AF_INET6, SOL_SOCKET, SO_REUSEADDR ...@@ -6,17 +6,12 @@ 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()
BACKLOG = 1024
PORT = 8000
response_fmt = \
"HTTP/1.0 200 OK\r\n" \
"Content-type: text/plain\r\n" \
"Content-length: {}\r\n" \
"\r\n" \
"{}"
def create_listening_socket(port): def create_listening_socket(port):
BACKLOG = 1024
sockfd = socket(AF_INET6, SOCK_STREAM) sockfd = socket(AF_INET6, SOCK_STREAM)
sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sockfd.bind(("", port)) sockfd.bind(("", port))
...@@ -33,6 +28,12 @@ def handle_connection(connfd, filepath): ...@@ -33,6 +28,12 @@ def handle_connection(connfd, filepath):
buf = connfd.recv(1024).decode("utf-8") buf = connfd.recv(1024).decode("utf-8")
length = buf.find("\r\n\r\n") length = buf.find("\r\n\r\n")
content = read_file(filepath) content = read_file(filepath)
response_fmt = \
"HTTP/1.0 200 OK\r\n" \
"Content-type: text/plain\r\n" \
"Content-length: {}\r\n" \
"\r\n" \
"{}"
response = response_fmt.format(len(content), content) response = response_fmt.format(len(content), content)
connfd.send(response.encode("utf-8")) connfd.send(response.encode("utf-8"))
connfd.close() connfd.close()
...@@ -44,6 +45,8 @@ def server_loop(sockfd, filepath): ...@@ -44,6 +45,8 @@ def server_loop(sockfd, filepath):
fork(lambda: handle_connection(connfd, filepath)) fork(lambda: handle_connection(connfd, filepath))
if __name__ == "__main__": if __name__ == "__main__":
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)
......
...@@ -33,7 +33,8 @@ class DesugarCompare(ast.NodeTransformer): ...@@ -33,7 +33,8 @@ class DesugarCompare(ast.NodeTransformer):
) )
if type(op) in (ast.NotIn, ast.IsNot): if type(op) in (ast.NotIn, ast.IsNot):
call = ast.UnaryOp(ast.Not(), call, **lnd) call = ast.UnaryOp(ast.Not(), call, **lnd)
call.orig_node = ast.Compare(left, [op], [right], **lnd)
res.values.append(call) res.values.append(call)
if len(res.values) == 1: if len(res.values) == 1:
return res.values[0] res = res.values[0]
return res return res
\ No newline at end of file
...@@ -57,7 +57,7 @@ class ExpressionVisitor(NodeVisitor): ...@@ -57,7 +57,7 @@ class ExpressionVisitor(NodeVisitor):
# TODO: escape sequences # TODO: escape sequences
yield f"\"{repr(node.value)[1:-1]}\"_ps" yield f"\"{repr(node.value)[1:-1]}\"_ps"
elif isinstance(node.value, bool): elif isinstance(node.value, bool):
yield str(node.value).lower() yield f"typon::TyBool({str(node.value).lower()})"
elif isinstance(node.value, int): elif isinstance(node.value, int):
# TODO: bigints # TODO: bigints
yield str(node.value) + "_pi" yield str(node.value) + "_pi"
...@@ -189,7 +189,7 @@ class ExpressionVisitor(NodeVisitor): ...@@ -189,7 +189,7 @@ class ExpressionVisitor(NodeVisitor):
yield from self.visit(node.type.deref().return_type) yield from self.visit(node.type.deref().return_type)
yield "{" yield "{"
yield "return" yield "return"
yield from self.reset().visit(node.body) yield from self.visit(node.body)
yield ";" yield ";"
yield "}" yield "}"
...@@ -239,9 +239,9 @@ class ExpressionVisitor(NodeVisitor): ...@@ -239,9 +239,9 @@ class ExpressionVisitor(NodeVisitor):
def visit_List(self, node: ast.List) -> Iterable[str]: def visit_List(self, node: ast.List) -> Iterable[str]:
if node.elts: if node.elts:
yield "typon::TyList{" yield "typon::TyList({"
yield from join(", ", map(self.visit, node.elts)) yield from join(", ", map(self.visit, node.elts))
yield "}" yield "})"
else: else:
yield from self.visit(node.type) yield from self.visit(node.type)
yield "{}" yield "{}"
...@@ -264,21 +264,24 @@ class ExpressionVisitor(NodeVisitor): ...@@ -264,21 +264,24 @@ class ExpressionVisitor(NodeVisitor):
yield "}" yield "}"
if node.keys: if node.keys:
yield from self.visit(node.type) #yield from self.visit(node.type)
yield "typon::TyDict("
yield "{" yield "{"
yield from join(", ", map(visit_item, node.keys, node.values)) yield from join(", ", map(visit_item, node.keys, node.values))
yield "}" yield "}"
yield ")"
else: else:
yield from self.visit(node.type) yield from self.visit(node.type)
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, TypeType) and isinstance(node.type.type_object, MonomorphizedUserType):
yield node.type.type_object.name # yield node.type.type_object.name
return # return
yield from self.prec("[]").visit(node.value) yield "("
yield "[" yield from self.visit(node.value)
yield from self.reset().visit(node.slice) yield ")["
yield from self.visit(node.slice)
yield "]" yield "]"
def visit_UnaryOp(self, node: ast.UnaryOp) -> Iterable[str]: def visit_UnaryOp(self, node: ast.UnaryOp) -> Iterable[str]:
......
...@@ -5,7 +5,7 @@ from typing import Iterable, Optional ...@@ -5,7 +5,7 @@ from typing import Iterable, Optional
from transpiler.phases.emit_cpp.expr import ExpressionVisitor from transpiler.phases.emit_cpp.expr import ExpressionVisitor
from transpiler.phases.typing.common import IsDeclare from transpiler.phases.typing.common import IsDeclare
from transpiler.phases.typing.scope import Scope from transpiler.phases.typing.scope import Scope
from transpiler.phases.emit_cpp.visitors import NodeVisitor, flatmap, CoroutineMode from transpiler.phases.emit_cpp.visitors import NodeVisitor, flatmap, CoroutineMode, join
from transpiler.phases.typing.types import CallableInstanceType, BaseType from transpiler.phases.typing.types import CallableInstanceType, BaseType
...@@ -13,11 +13,15 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]: ...@@ -13,11 +13,15 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]:
yield f"struct : referencemodel::function {{" yield f"struct : referencemodel::function {{"
yield "typon::Task<typon::TyNone> operator()(" yield "typon::Task<typon::TyNone> operator()("
for arg, ty in zip(func.block_data.node.args.args, func.parameters): def emit_arg(arg, ty):
yield "auto " yield "auto"
yield arg yield arg.arg
yield from join(",", (emit_arg(arg, ty) for arg, ty in zip(func.block_data.node.args.args, func.parameters)))
yield ") const {" yield ") const {"
for rd in func.block_data.scope.root_decls:
pass
yield from BlockVisitor(func.block_data.scope, generator=CoroutineMode.TASK).visit(func.block_data.node.body) yield from BlockVisitor(func.block_data.scope, generator=CoroutineMode.TASK).visit(func.block_data.node.body)
yield "co_return {};" yield "co_return {};"
yield "}" yield "}"
...@@ -152,14 +156,15 @@ class BlockVisitor(NodeVisitor): ...@@ -152,14 +156,15 @@ class BlockVisitor(NodeVisitor):
# #
# yield "}" # yield "}"
# #
def visit_lvalue(self, lvalue: ast.expr, declare: IsDeclare) -> Iterable[str]: def visit_lvalue(self, lvalue: ast.expr, declare: IsDeclare, allow_auto: bool = False) -> Iterable[str]:
if isinstance(lvalue, ast.Tuple): if isinstance(lvalue, ast.Tuple):
raise NotImplementedError()
# for name, decl, ty in zip(lvalue.elts, declare, lvalue.type.args): # for name, decl, ty in zip(lvalue.elts, declare, lvalue.type.args):
# if decl: # if decl:
# yield from self.visit_lvalue(name, True) # yield from self.visit_lvalue(name, True)
# yield ";" # yield ";"
# yield f"std::tie({', '.join(flatmap(self.visit_lvalue, lvalue.elts))})" def helper(args):
return self.visit_lvalue(*args)
yield f"std::tie({', '.join(flatmap(helper, zip(lvalue.elts, declare.detail)))})"
elif isinstance(lvalue, ast.Name): elif isinstance(lvalue, ast.Name):
if lvalue.id == "_": if lvalue.id == "_":
if not declare: if not declare:
...@@ -171,6 +176,9 @@ class BlockVisitor(NodeVisitor): ...@@ -171,6 +176,9 @@ class BlockVisitor(NodeVisitor):
# yield self.scope.declare(name, (" ".join(self.expr().visit(val)), val) if val else None, # yield self.scope.declare(name, (" ".join(self.expr().visit(val)), val) if val else None,
# getattr(val, "is_future", False)) # getattr(val, "is_future", False))
if declare: if declare:
if allow_auto:
yield "auto"
else:
yield "decltype(" yield "decltype("
yield from self.expr().visit(declare.initial_value) yield from self.expr().visit(declare.initial_value)
yield ")" yield ")"
...@@ -186,18 +194,30 @@ class BlockVisitor(NodeVisitor): ...@@ -186,18 +194,30 @@ class BlockVisitor(NodeVisitor):
def visit_Assign(self, node: ast.Assign) -> Iterable[str]: def visit_Assign(self, node: ast.Assign) -> Iterable[str]:
if len(node.targets) != 1: if len(node.targets) != 1:
raise NotImplementedError(node) raise NotImplementedError(node)
yield from self.visit_lvalue(node.targets[0], node.is_declare) yield from self.visit_lvalue(node.targets[0], node.is_declare, True)
yield " = " yield " = "
yield from self.expr().visit(node.value) yield from self.expr().visit(node.value)
yield ";" yield ";"
def visit_AnnAssign(self, node: ast.AnnAssign) -> Iterable[str]: def visit_AnnAssign(self, node: ast.AnnAssign) -> Iterable[str]:
yield from self.visit_lvalue(node.target, node.is_declare) yield from self.visit_lvalue(node.target, node.is_declare, node.value is not None)
if node.value: if node.value:
yield " = " yield " = "
yield from self.expr().visit(node.value) yield from self.expr().visit(node.value)
yield ";" yield ";"
def visit_If(self, node: ast.If) -> Iterable[str]:
yield "if ("
yield from self.expr().visit(node.test)
yield ")"
yield from self.emit_block(node.inner_scope, node.body)
if node.orelse:
yield "else "
if isinstance(node.orelse, ast.If):
yield from self.visit(node.orelse)
else:
yield from self.emit_block(node.orelse_scope, node.orelse)
def visit_For(self, node: ast.For) -> Iterable[str]: def visit_For(self, node: ast.For) -> Iterable[str]:
if not isinstance(node.target, ast.Name): if not isinstance(node.target, ast.Name):
...@@ -216,8 +236,35 @@ class BlockVisitor(NodeVisitor): ...@@ -216,8 +236,35 @@ class BlockVisitor(NodeVisitor):
yield ")" yield ")"
yield from self.emit_block(node.inner_scope, node.orelse) yield from self.emit_block(node.inner_scope, node.orelse)
def visit_While(self, node: ast.While) -> Iterable[str]:
if node.orelse:
yield "auto"
yield node.orelse_variable
yield "= true;"
yield "while ("
yield from self.expr().visit(node.test)
yield ")"
yield from self.emit_block(node.inner_scope, node.body)
if node.orelse:
yield "if ("
yield node.orelse_variable
yield ")"
yield from self.emit_block(node.inner_scope, node.orelse)
def emit_block(self, scope: Scope, items: Iterable[ast.stmt]) -> Iterable[str]: def emit_block(self, scope: Scope, items: Iterable[ast.stmt]) -> Iterable[str]:
yield "{" yield "{"
for child in items: for child in items:
yield from BlockVisitor(scope, generator=self.generator).visit(child) yield from BlockVisitor(scope, generator=self.generator).visit(child)
yield "}" yield "}"
def visit_Return(self, node: ast.Return) -> Iterable[str]:
if CoroutineMode.ASYNC in self.generator:
yield "co_return "
else:
yield "return "
if node.value:
yield from self.expr().visit(node.value)
yield ";"
...@@ -3,7 +3,7 @@ from typing import Iterable ...@@ -3,7 +3,7 @@ from typing import Iterable
from transpiler.phases.emit_cpp.class_ import emit_class from transpiler.phases.emit_cpp.class_ import emit_class
from transpiler.phases.emit_cpp.function import emit_function from transpiler.phases.emit_cpp.function import emit_function
from transpiler.phases.typing.modules import ModuleType from transpiler.phases.typing.modules import ModuleType
from transpiler.phases.typing.types import CallableInstanceType, ClassTypeType from transpiler.phases.typing.types import CallableInstanceType, ClassTypeType, TypeVariable
def emit_module(mod: ModuleType) -> Iterable[str]: def emit_module(mod: ModuleType) -> Iterable[str]:
...@@ -17,6 +17,8 @@ def emit_module(mod: ModuleType) -> Iterable[str]: ...@@ -17,6 +17,8 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
if not field.in_class_def: if not field.in_class_def:
continue continue
ty = field.type.deref() ty = field.type.deref()
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():
......
...@@ -69,7 +69,9 @@ class NodeVisitor(UniversalVisitor): ...@@ -69,7 +69,9 @@ class NodeVisitor(UniversalVisitor):
case types.TY_STR: case types.TY_STR:
yield "typon::TyStr" yield "typon::TyStr"
case types.TypeVariable(name): case types.TypeVariable(name):
raise UnresolvedTypeVariableError(node) yield f"$VAR__{name}"
#raise UnresolvedTypeVariableError(node)
case types.GenericInstanceType(): case types.GenericInstanceType():
yield from self.visit(node.generic_parent) yield from self.visit(node.generic_parent)
yield "<" yield "<"
......
...@@ -72,9 +72,9 @@ PRECEDENCE_LEVELS = {op: i for i, ops in enumerate(PRECEDENCE) for op in ops} ...@@ -72,9 +72,9 @@ PRECEDENCE_LEVELS = {op: i for i, ops in enumerate(PRECEDENCE) for op in ops}
"""Mapping of C++ operators to their precedence level.""" """Mapping of C++ operators to their precedence level."""
MAPPINGS = { MAPPINGS = {
"True": "true", "True": "typon::TyBool(true)",
"False": "false", "False": "typon::TyBool(false)",
"None": "nullptr", "None": "typon::TyNone{}",
"operator": "operator_", "operator": "operator_",
} }
"""Mapping of Python builtin constants to C++ equivalents.""" """Mapping of Python builtin constants to C++ equivalents."""
from transpiler.phases.typing.common import PRELUDE from transpiler.phases.typing.common import PRELUDE
from transpiler.phases.typing.scope import VarKind, VarDecl from transpiler.phases.typing.scope import VarKind, VarDecl
from transpiler.phases.typing.types import TY_TASK, TY_CALLABLE, TY_OPTIONAL, TY_CPP_TYPE, TY_BUILTIN_FEATURE, TY_TUPLE, \ from transpiler.phases.typing.types import TY_TASK, TY_CALLABLE, TY_OPTIONAL, TY_CPP_TYPE, TY_BUILTIN_FEATURE, TY_TUPLE, \
TY_DICT, TY_SET, TY_LIST, TY_COMPLEX, TY_BYTES, TY_STR, TY_FLOAT, TY_INT, TY_BOOL, TY_OBJECT TY_DICT, TY_SET, TY_LIST, TY_COMPLEX, TY_BYTES, TY_STR, TY_FLOAT, TY_INT, TY_BOOL, TY_OBJECT, TY_JOIN, TY_FUTURE, \
TY_FORKED, TY_GENERATOR
prelude_vars = { prelude_vars = {
"object": TY_OBJECT, "object": TY_OBJECT,
...@@ -17,7 +18,11 @@ prelude_vars = { ...@@ -17,7 +18,11 @@ prelude_vars = {
"tuple": TY_TUPLE, "tuple": TY_TUPLE,
"BuiltinFeature": TY_BUILTIN_FEATURE, "BuiltinFeature": TY_BUILTIN_FEATURE,
"CppType": TY_CPP_TYPE, "CppType": TY_CPP_TYPE,
"Task": TY_TASK "Task": TY_TASK,
"Join": TY_JOIN,
"Future": TY_FUTURE,
"Forked": TY_FORKED,
"Generator": TY_GENERATOR,
} }
PRELUDE.vars.update({name: VarDecl(VarKind.LOCAL, ty.type_type()) for name, ty in prelude_vars.items()}) PRELUDE.vars.update({name: VarDecl(VarKind.LOCAL, ty.type_type()) for name, ty in prelude_vars.items()})
......
...@@ -5,7 +5,8 @@ import importlib ...@@ -5,7 +5,8 @@ import importlib
from dataclasses import dataclass from dataclasses import dataclass
from transpiler.exceptions import CompileError from transpiler.exceptions import CompileError
from transpiler.phases.typing.types import BaseType, TypeVariable from transpiler.phases.typing.types import BaseType, TypeVariable, CallableInstanceType, TY_NONE, PromiseInstanceType, \
TupleInstanceType, RuntimeValue, PromiseKind
from transpiler.utils import highlight, linenodata from transpiler.utils import highlight, linenodata
from transpiler.phases.typing.common import ScoperVisitor, is_builtin, DeclareInfo from transpiler.phases.typing.common import ScoperVisitor, is_builtin, DeclareInfo
from transpiler.phases.typing.expr import ScoperExprVisitor, DUNDER from transpiler.phases.typing.expr import ScoperExprVisitor, DUNDER
...@@ -80,8 +81,8 @@ class ScoperBlockVisitor(ScoperVisitor): ...@@ -80,8 +81,8 @@ class ScoperBlockVisitor(ScoperVisitor):
raise NotImplementedError(node) raise NotImplementedError(node)
target = node.targets[0] target = node.targets[0]
ty = self.get_type(node.value) ty = self.get_type(node.value)
decl = self.visit_assign_target(target, ty) decl = self.visit_assign_target(target, ty, node.value)
node.is_declare = DeclareInfo(node.value) if decl else None node.is_declare = DeclareInfo(decl, node.value) if decl else None
def visit_AnnAssign(self, node: ast.AnnAssign): def visit_AnnAssign(self, node: ast.AnnAssign):
if node.simple != 1: if node.simple != 1:
...@@ -89,14 +90,14 @@ class ScoperBlockVisitor(ScoperVisitor): ...@@ -89,14 +90,14 @@ class ScoperBlockVisitor(ScoperVisitor):
if not isinstance(node.target, ast.Name): if not isinstance(node.target, ast.Name):
raise NotImplementedError(node) raise NotImplementedError(node)
ty = self.visit_annotation(node.annotation) ty = self.visit_annotation(node.annotation)
decl = self.visit_assign_target(node.target, ty) decl = self.visit_assign_target(node.target, ty, node.value)
node.is_declare = DeclareInfo(node.value) if decl else None node.is_declare = DeclareInfo(decl, node.value) if decl else None
if node.value is not None: if node.value is not None:
ty_val = self.get_type(node.value) ty_val = self.get_type(node.value)
__TB__ = f"unifying annotation {highlight(node.annotation)} with value {highlight(node.value)} of type {highlight(ty_val)}" __TB__ = f"unifying annotation {highlight(node.annotation)} with value {highlight(node.value)} of type {highlight(ty_val)}"
ty.unify(ty_val) ty.unify(ty_val)
def visit_assign_target(self, target, decl_val: BaseType) -> bool: def visit_assign_target(self, target, decl_val: BaseType, val: ast.expr = None) -> bool:
__TB__ = f"analyzing assignment target {highlight(target)} with value {highlight(decl_val)}" __TB__ = f"analyzing assignment target {highlight(target)} with value {highlight(decl_val)}"
if isinstance(target, ast.Name): if isinstance(target, ast.Name):
if target.id == "_": if target.id == "_":
...@@ -107,20 +108,26 @@ class ScoperBlockVisitor(ScoperVisitor): ...@@ -107,20 +108,26 @@ class ScoperBlockVisitor(ScoperVisitor):
vdecl.type.unify(decl_val) vdecl.type.unify(decl_val)
return False return False
else: else:
self.scope.vars[target.id] = VarDecl(VarKind.LOCAL, decl_val) # self.scope.vars[target.id] = VarDecl(VarKind.LOCAL, decl_val)
# if self.scope.kind == ScopeKind.FUNCTION_INNER:
# self.root_decls[target.id] = VarDecl(VarKind.OUTER_DECL, decl_val)
# return False
# return True
val = val or RuntimeValue()
self.scope.function.vars[target.id] = VarDecl(VarKind.LOCAL, decl_val, val)
if self.scope.kind == ScopeKind.FUNCTION_INNER: if self.scope.kind == ScopeKind.FUNCTION_INNER:
self.root_decls[target.id] = VarDecl(VarKind.OUTER_DECL, decl_val) self.scope.function.root_decls[target.id] = val
return False return False
return True return True
elif isinstance(target, ast.Tuple): elif isinstance(target, ast.Tuple):
if not isinstance(decl_val, TupleType): if not isinstance(decl_val, TupleInstanceType):
from transpiler.phases.typing.exceptions import InvalidUnpackError from transpiler.phases.typing.exceptions import InvalidUnpackError
raise InvalidUnpackError(decl_val) raise InvalidUnpackError(decl_val)
if len(target.elts) != len(decl_val.args): if len(target.elts) != len(decl_val.fields):
from transpiler.phases.typing.exceptions import InvalidUnpackCountError from transpiler.phases.typing.exceptions import InvalidUnpackCountError
raise InvalidUnpackCountError(decl_val, len(target.elts)) raise InvalidUnpackCountError(decl_val, len(target.elts))
target.type = decl_val target.type = decl_val
decls = [self.visit_assign_target(t, ty) for t, ty in zip(target.elts, decl_val.args)] # eager evaluated decls = [self.visit_assign_target(t, ty, ast.Name(str(t))) for t, ty in zip(target.elts, decl_val.fields)] # eager evaluated
return decls return decls
elif isinstance(target, ast.Attribute): elif isinstance(target, ast.Attribute):
attr_type = self.expr().visit(target) attr_type = self.expr().visit(target)
...@@ -202,9 +209,11 @@ class ScoperBlockVisitor(ScoperVisitor): ...@@ -202,9 +209,11 @@ class ScoperBlockVisitor(ScoperVisitor):
from transpiler.phases.typing.exceptions import OutsideFunctionError from transpiler.phases.typing.exceptions import OutsideFunctionError
raise OutsideFunctionError() raise OutsideFunctionError()
ftype = fct.obj_type ftype = fct.obj_type
assert isinstance(ftype, FunctionType) assert isinstance(ftype, CallableInstanceType)
vtype = self.expr().visit(node.value) if node.value else TY_NONE vtype = self.expr().visit(node.value) if node.value else TY_NONE
vtype.unify(ftype.return_type.return_type if isinstance(ftype.return_type, Promise) else ftype.return_type) vtype.unify(ftype.return_type.deref()
if isinstance(ftype.return_type.resolve(), PromiseInstanceType)
else ftype.return_type)
self.scope.diverges = True self.scope.diverges = True
#fct.has_return = True #fct.has_return = True
......
...@@ -129,6 +129,7 @@ def is_builtin(x, feature): ...@@ -129,6 +129,7 @@ def is_builtin(x, feature):
@dataclass @dataclass
class DeclareInfo: class DeclareInfo:
detail: bool | list[bool]
initial_value: Optional[ast.expr] = None initial_value: Optional[ast.expr] = None
......
...@@ -8,7 +8,7 @@ from transpiler.phases.typing.common import ScoperVisitor, is_builtin ...@@ -8,7 +8,7 @@ from transpiler.phases.typing.common import ScoperVisitor, is_builtin
from transpiler.phases.typing.exceptions import ArgumentCountMismatchError, TypeMismatchKind, TypeMismatchError from transpiler.phases.typing.exceptions import ArgumentCountMismatchError, TypeMismatchKind, TypeMismatchError
from transpiler.phases.typing.types import BaseType, TY_STR, TY_BOOL, TY_INT, TY_COMPLEX, TY_FLOAT, TY_NONE, \ 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, \ ClassTypeType, ResolvedConcreteType, GenericType, CallableInstanceType, TY_LIST, TY_SET, TY_DICT, RuntimeValue, \
TypeVariable, TY_LAMBDA, TypeListType, MethodType, TY_TUPLE TypeVariable, TY_LAMBDA, TypeListType, MethodType, TY_TUPLE, PromiseInstanceType
from transpiler.phases.typing.scope import ScopeKind, VarDecl, VarKind from transpiler.phases.typing.scope import ScopeKind, VarDecl, VarKind
from transpiler.utils import linenodata from transpiler.utils import linenodata
...@@ -52,7 +52,7 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -52,7 +52,7 @@ class ScoperExprVisitor(ScoperVisitor):
return res return res
def visit_Tuple(self, node: ast.Tuple) -> BaseType: def visit_Tuple(self, node: ast.Tuple) -> BaseType:
return TY_TUPLE.instantiate_(*[self.visit(e) for e in node.elts]) return TY_TUPLE.instantiate([self.visit(e) for e in node.elts])
def visit_Slice(self, node: ast.Slice) -> BaseType: def visit_Slice(self, node: ast.Slice) -> BaseType:
for n in ("lower", "upper", "step"): for n in ("lower", "upper", "step"):
...@@ -112,13 +112,13 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -112,13 +112,13 @@ class ScoperExprVisitor(ScoperVisitor):
rtype = self.visit_function_call(ftype, [self.visit(arg) for arg in node.args]) rtype = self.visit_function_call(ftype, [self.visit(arg) for arg in node.args])
actual = rtype actual = rtype
node.is_await = False node.is_await = False
# if isinstance(actual, Promise) and actual.kind != PromiseKind.GENERATOR: if isinstance(actual, PromiseInstanceType): # and actual.kind != PromiseKind.GENERATOR: TODO
# node.is_await = True node.is_await = True
# actual = actual.return_type.resolve() actual = actual.value.resolve()
#
# if self.scope.function and isinstance(actual, Promise) and actual.kind == PromiseKind.FORKED \ if self.scope.function and isinstance(actual, Promise) and actual.kind == PromiseKind.FORKED \
# and isinstance(fty := self.scope.function.obj_type.return_type, Promise): and isinstance(fty := self.scope.function.obj_type.return_type, Promise):
# fty.kind = PromiseKind.JOIN fty.kind = PromiseKind.JOIN
return actual return actual
...@@ -141,11 +141,17 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -141,11 +141,17 @@ class ScoperExprVisitor(ScoperVisitor):
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)
if not ftype.is_native:
pname = ftype.block_data.node.args.args[i].arg
ftype.block_data.scope.declare_local(pname, b)
if not ftype.is_native: if not ftype.is_native:
from transpiler.phases.typing.block import ScoperBlockVisitor from transpiler.phases.typing.block import ScoperBlockVisitor
vis = ScoperBlockVisitor(ftype.block_data.scope) scope = ftype.block_data.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)
#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):
# init: FunctionType = self.visit_getattr(ftype, "__init__").remove_self() # init: FunctionType = self.visit_getattr(ftype, "__init__").remove_self()
...@@ -311,7 +317,7 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -311,7 +317,7 @@ class ScoperExprVisitor(ScoperVisitor):
gen: ast.comprehension = node.generators[0] gen: ast.comprehension = node.generators[0]
iter_type = self.get_iter(self.visit(gen.iter)) iter_type = self.get_iter(self.visit(gen.iter))
node.input_item_type = self.get_next(iter_type) node.input_item_type = self.get_next(iter_type)
virt_scope = self.scope.child(ScopeKind.FUNCTION_INNER) virt_scope = self.scope.child(ScopeKind.FUNCTION)
from transpiler.phases.typing.block import ScoperBlockVisitor from transpiler.phases.typing.block import ScoperBlockVisitor
visitor = ScoperBlockVisitor(virt_scope) visitor = ScoperBlockVisitor(virt_scope)
visitor.visit_assign_target(gen.target, node.input_item_type) visitor.visit_assign_target(gen.target, node.input_item_type)
......
...@@ -54,6 +54,7 @@ class Scope: ...@@ -54,6 +54,7 @@ class Scope:
diverges: bool = False diverges: bool = False
class_: Optional["Scope"] = None class_: Optional["Scope"] = None
is_loop: Optional[ast.For | ast.While] = None is_loop: Optional[ast.For | ast.While] = None
root_decls: Dict[str, ast.expr] = field(default_factory=dict)
@staticmethod @staticmethod
def make_global(): def make_global():
......
...@@ -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 MethodType, UniqueTypeMixin, GenericType, BlockData, TY_TASK
from transpiler.phases.utils import NodeVisitorSeq from transpiler.phases.utils import NodeVisitorSeq
def visit_generic_item( def visit_generic_item(
...@@ -158,6 +158,8 @@ class StdlibVisitor(NodeVisitorSeq): ...@@ -158,6 +158,8 @@ class StdlibVisitor(NodeVisitorSeq):
def visit_FunctionDef(self, node: ast.FunctionDef): def visit_FunctionDef(self, node: ast.FunctionDef):
def visit_nongeneric(scope, output: CallableInstanceType): def visit_nongeneric(scope, output: CallableInstanceType):
scope = scope.child(ScopeKind.FUNCTION) scope = scope.child(ScopeKind.FUNCTION)
scope.function = scope
scope.obj_type = output
arg_visitor = TypeAnnotationVisitor(scope) arg_visitor = TypeAnnotationVisitor(scope)
output.block_data = BlockData(node, scope) output.block_data = BlockData(node, scope)
output.parameters = [arg_visitor.visit(arg.annotation) for arg in node.args.args] output.parameters = [arg_visitor.visit(arg.annotation) for arg in node.args.args]
...@@ -165,6 +167,8 @@ class StdlibVisitor(NodeVisitorSeq): ...@@ -165,6 +167,8 @@ class StdlibVisitor(NodeVisitorSeq):
output.optional_at = len(node.args.args) - len(node.args.defaults) output.optional_at = len(node.args.args) - len(node.args.defaults)
output.is_variadic = args.vararg is not None output.is_variadic = args.vararg is not None
output.is_native = self.is_native output.is_native = self.is_native
if not self.is_native:
output.return_type = TY_TASK.instantiate([output.return_type])
@dataclass(eq=False, init=False) @dataclass(eq=False, init=False)
class InstanceType(CallableInstanceType): class InstanceType(CallableInstanceType):
......
...@@ -147,6 +147,11 @@ class TypeVariable(ConcreteType): ...@@ -147,6 +147,11 @@ class TypeVariable(ConcreteType):
def contains_internal(self, other: BaseType) -> bool: def contains_internal(self, other: BaseType) -> bool:
return self.resolve() is other.resolve() return self.resolve() is other.resolve()
def deref(self):
if self.resolved is None:
return self
return self.resolved.deref()
@dataclass(eq=False) @dataclass(eq=False)
...@@ -282,6 +287,13 @@ class GenericInstanceType(ResolvedConcreteType): ...@@ -282,6 +287,13 @@ class GenericInstanceType(ResolvedConcreteType):
# is this correct? # is this correct?
return self == other or any(a.contains(other) for a in self.generic_args) return self == other or any(a.contains(other) for a in self.generic_args)
class PromiseKind(enum.Enum):
TASK = 0
JOIN = 1
FUTURE = 2
FORKED = 3
GENERATOR = 4
class GenericParameterKind(enum.Enum): class GenericParameterKind(enum.Enum):
NORMAL = enum.auto() NORMAL = enum.auto()
TUPLE = enum.auto() TUPLE = enum.auto()
...@@ -303,6 +315,7 @@ class GenericConstraint: ...@@ -303,6 +315,7 @@ class GenericConstraint:
@dataclass(eq=False, init=False) @dataclass(eq=False, init=False)
class GenericType(BaseType): class GenericType(BaseType):
parameters: list[GenericParameter] parameters: list[GenericParameter]
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]:
return [] return []
...@@ -329,6 +342,11 @@ class GenericType(BaseType): ...@@ -329,6 +342,11 @@ class GenericType(BaseType):
def deref(self): def deref(self):
return self.instantiate_default().deref() return self.instantiate_default().deref()
def cache_instance(self, instance):
if not hasattr(self, "instance_cache"):
self.instance_cache = {}
self.instance_cache[tuple(instance.generic_args)] = instance
@dataclass(eq=False, init=False) @dataclass(eq=False, init=False)
class BuiltinGenericType(UniqueTypeMixin, GenericType): class BuiltinGenericType(UniqueTypeMixin, GenericType):
...@@ -388,23 +406,45 @@ TY_DICT = create_builtin_generic_type("dict") ...@@ -388,23 +406,45 @@ TY_DICT = create_builtin_generic_type("dict")
TY_TUPLE = create_builtin_generic_type("tuple") TY_TUPLE = create_builtin_generic_type("tuple")
@dataclass(eq=False) @dataclass(eq=False)
class TaskInstanceType(GenericInstanceType): class PromiseInstanceType(GenericInstanceType):
value: ConcreteType value: ConcreteType
def deref(self): def deref(self):
match self.generic_parent.kind:
case PromiseKind.TASK | PromiseKind.JOIN:
return self.value.deref() return self.value.deref()
case _:
return self
@dataclass(eq=False)
class PromiseType(UniqueTypeMixin, GenericType):
kind: PromiseKind
class TaskType(UniqueTypeMixin, GenericType):
def name(self): def name(self):
match self.kind:
case PromiseKind.TASK:
return "Task" return "Task"
case PromiseKind.JOIN:
return "Join"
case PromiseKind.FUTURE:
return "Future"
case PromiseKind.FORKED:
return "Forked"
case PromiseKind.GENERATOR:
return "Generator"
def _instantiate(self, args: list[ConcreteType]) -> GenericInstanceType: def _instantiate(self, args: list[ConcreteType]) -> GenericInstanceType:
assert len(args) == 1 assert len(args) == 1
return TaskInstanceType(args[0]) return PromiseInstanceType(args[0])
TY_TASK = PromiseType([GenericParameter("T")], PromiseKind.TASK)
TY_JOIN = PromiseType([GenericParameter("T")], PromiseKind.JOIN)
TY_FUTURE = PromiseType([GenericParameter("T")], PromiseKind.FUTURE)
TY_FORKED = PromiseType([GenericParameter("T")], PromiseKind.FORKED)
TY_GENERATOR = PromiseType([GenericParameter("T")], PromiseKind.GENERATOR)
TY_TASK = TaskType()
TY_TUPLE.instantiate_ = lambda args: TupleInstanceType(args) TY_TUPLE.instantiate_ = lambda args: TupleInstanceType(args)
......
...@@ -63,12 +63,15 @@ def transpile(source, name: str, path: Path): ...@@ -63,12 +63,15 @@ def transpile(source, name: str, path: Path):
yield f"co_await dot(PROGRAMNS::{module.name()}, main)();" yield f"co_await dot(PROGRAMNS::{module.name()}, main)();"
yield "}" yield "}"
yield "int main(int argc, char* argv[]) {" yield "int main(int argc, char* argv[]) {"
yield "py_sys::all.argv = typon::TyList<TyStr>(std::vector<TyStr>(argv, argv + argc));" yield "py_sys::all.argv = typon::TyList__oo<>::Obj(std::vector<typon::TyStr__oo<>::Obj>(argv, argv + argc));"
yield f"root().call();" yield f"root().call();"
yield "}" yield "}"
yield "#endif" yield "#endif"
code = "\n".join(filter(None, main_module())) code = main_module()
code = filter(None, code)
code = list(code)
code = "\n".join(code)
return code return code
......
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