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

Give up

parent 647b5c06
......@@ -62,95 +62,6 @@ template <PySmartPtr T> struct RealType<T> {
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 {};
} // namespace typon
......@@ -169,7 +80,7 @@ concept PyIterable = requires(T t) {
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) {
{ t.size() } -> std::same_as<size_t>;
};
......@@ -181,11 +92,16 @@ concept PyLen = requires(const T &t) {
template <CppSize T>
requires(!PyLen<T>)
size_t len(const T &t) {
auto len(const T &t) {
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>
concept PyNext = requires(T t) {
......@@ -474,7 +390,7 @@ using InterpGuard = py::scoped_interpreter;
template <typename T>
concept HasSync = requires(T t) {
{ t.sync() } -> std::same_as<T>;
};
};
/*auto call_sync(auto f, auto... args) {
if constexpr (HasSync<decltype(f)>) {
......@@ -486,11 +402,12 @@ concept HasSync = requires(T t) {
auto call_sync(auto 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 {
return f;
}
}
#endif // TYPON_BUILTINS_HPP
......@@ -149,7 +149,6 @@ 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;
......@@ -172,7 +171,8 @@ struct TyDict__oo : classtype<_Base0, TyDict__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;
......
......@@ -17,22 +17,20 @@ template <typename _Base0 = object>
struct TyList__oo : classtype<_Base0, TyList__oo<>> {
struct : method {
template <typename Self> auto operator()(Self self) const {
auto operator()(auto self) const {
return TyList__oo<>{}(self->_v);
}
} static constexpr copy{};
struct : method {
template <typename Self, typename Other>
auto operator()(Self self, Other other) const {
auto operator()(auto self, auto 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 operator()(auto self, auto other) const {
auto result = TyList__oo<>{}(self->_v);
dot(result, extend)(other);
return result;
......@@ -40,8 +38,7 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> {
} static constexpr oo__add__oo{};
struct : method {
template <typename Self, typename Other>
auto operator()(Self self, Other other) const {
auto operator()(auto self, auto other) const {
auto result = TyList__oo<>{}(self->_v);
result->_v->reserve(result->_v->size() * other);
for (int i = 0; i < other - 1; i++) {
......@@ -52,7 +49,7 @@ struct TyList__oo : classtype<_Base0, TyList__oo<>> {
} static constexpr oo__mul__oo{};
struct : method {
template <typename Self> auto operator()(Self self) const {
auto operator()(auto self) const {
std::stringstream s;
s << '[';
if (self->_v->size() > 0) {
......@@ -69,6 +66,23 @@ struct TyList__oo : classtype<_Base0, TyList__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>> {
using value_type = T;
......
......@@ -173,6 +173,10 @@ struct TyStr__oo : classtype<_Base0, TyStr__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> {
std::string value;
......
......@@ -826,8 +826,8 @@ private:
template <typename T, typename O> struct instance : T {
using type = T;
static constexpr std::string_view repr =
meta::join<object::object_of_, T::repr>;
/*static constexpr std::string_view repr =
meta::join<object::object_of_, T::repr>;*/
const O *operator->() const { return static_cast<const O *>(this); }
O *operator->() { return static_cast<O *>(this); }
......@@ -839,7 +839,7 @@ template <typename B, typename T> struct classtype : B {
using base = B;
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); }
T *operator->() { return static_cast<T *>(this); }
......@@ -866,7 +866,7 @@ using rebase = typename rebase_s<std::remove_cvref_t<T>>::template type<Rebase>;
template <typename M> struct moduletype : object {
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); }
M *operator->() { return static_cast<M *>(this); }
......@@ -1139,6 +1139,24 @@ SIMPLE_OP(!=, ne)
SIMPLE_OP(>, gt)
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
#endif // REFERENCEMODEL_H
......@@ -11,7 +11,8 @@
#include <tuple>
namespace py_socket {
struct socket_t {
template <typename _Unused = void>
struct socket__oo : referencemodel::moduletype<socket__oo<>> {
#undef SOCK_STREAM
#undef AF_INET6
#undef SOL_SOCKET
......@@ -23,19 +24,77 @@ struct socket_t {
static constexpr int SO_REUSEADDR = 2;
static constexpr int AF_UNIX = 1;
struct socket_s {
struct py_type {
METHOD(typon::Task<std::tuple<TyObj<py_type> COMMA() std::string>>,
accept, (Self self), {
template <typename _Base0 = object>
struct socket_t__oo : referencemodel::classtype<_Base0, socket_t__oo<>> {
static auto create_socket(auto fd) {
struct Obj : referencemodel::instance<socket_t__oo<>, Obj> {
/*Obj(int fd = -1) : fd(fd) {}
Obj(const Obj &other) : fd(other.fd) {}*/
int fd;
};
return Obj{fd};
}
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(tyObj<py_type>(connfd),
std::string("")); // TODO
})
co_return std::make_tuple(rc(create_socket(connfd)),
""_ps); // TODO
}
} static constexpr accept{};
METHOD(typon::Task<void>, close, (Self self),
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) {
co_await dot(self, close)();
system_error(errno, "listen()");
}
co_return {};
}
} static constexpr listen{};
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), {
......@@ -79,25 +138,23 @@ struct socket_t {
co_await dotp(self, close)();
system_error(-sbytes, "send()");
}
})
})*/
py_type(int fd = -1) : fd(fd) {}
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) {
return tyObj<py_type>(fd);
return rc(create_socket(fd));
} else {
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,
int proto = 0, int flags = 0),
{
......@@ -116,14 +173,13 @@ struct socket_t {
system_error(err, "getaddrinfo()");
}
return res;
})
} all;
auto &get_all() { return all; }
})*/
};
socket__oo<> all;
} // namespace py_socket
namespace typon {
using PySocket = TyObj<py_socket::socket_t::socket_s>;
// using PySocket = TyObj<py_socket::socket_t::socket_s>;
}
#endif // TYPON_SOCKET_HPP
......@@ -9,16 +9,20 @@
#include <iostream>
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 &stdout = std::cout;
static constexpr auto &stderr = std::cerr;
typon::TyList__oo<>::Obj<typon::TyStr__oo<>::Obj> argv;
FUNCTION(void, exit, (int code), { std::exit(code); })
} all;
/*FUNCTION(void, exit, (int code), { std::exit(code); })*/
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
#endif // TYPON_SYS_HPP
......@@ -180,3 +180,39 @@ class Exception:
def __init__(self, message: str) -> None: ...
assert next([])
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:
return False
......@@ -5,8 +5,11 @@
#
#
# @dataclass
# class Thing[T]:
# x: T
class Thing[T]:
x: T
def __init__(self, y):
pass
# def f[T](x: T):
......@@ -15,12 +18,9 @@
#
#
#
# if __name__ == "__main__":
# a = Thing[int](1)
# b = Thing[str]("abc")
# print(a)
# print(b)
if __name__ == "__main__":
print("abc")
\ No newline at end of file
a = Thing(1)
b = Thing("abc")
print(a)
print(b)
......@@ -3,7 +3,7 @@
import sys
from socket import socket, SOCK_STREAM, AF_INET6, SOL_SOCKET, SO_REUSEADDR
from typon import fork
#from typon import fork
#fork = lambda x: x()
......@@ -40,18 +40,19 @@ def handle_connection(connfd, filepath):
def server_loop(sockfd, filepath):
while True:
connfd, _ = sockfd.accept()
x = sockfd.accept()
fork(lambda: handle_connection(connfd, filepath))
#fork(lambda: handle_connection(connfd, filepath))
if __name__ == "__main__":
PORT = 8000
if len(sys.argv) > 2:
print("Usage: webserver [ filepath ]")
sys.exit(1)
# if len(sys.argv) > 2:
# print("Usage: webserver [ filepath ]")
# 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)
sockfd = create_listening_socket(PORT)
......
import ast
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"struct {node.name}__oo : referencemodel::classtype<_Base0, {node.name}__oo<>> {{"
yield f"static constexpr std::string_view name = \"{node.name}\";"
yield f"struct {name}__oo : referencemodel::classtype<_Base0, {name}__oo<>> {{"
yield f"static constexpr std::string_view name = \"{name}\";"
inner = ClassInnerVisitor2(node.inner_scope)
for stmt in node.body:
yield from inner.visit(stmt)
# inner = ClassInnerVisitor2(node.inner_scope)
# for stmt in node.body:
# 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)
for stmt in node.body:
yield from inner.visit(stmt)
# inner = ClassInnerVisitor4(node.inner_scope)
# for stmt in node.body:
# yield from inner.visit(stmt)
yield "template <typename... U>"
yield "Obj(U&&... args) {"
......@@ -31,5 +33,5 @@ def emit_class(node: ast.ClassDef) -> Iterable[str]:
yield "}"
yield f"}};"
yield f"static constexpr {node.name}__oo<> {node.name} {{}};"
yield f"static_assert(sizeof {node.name} == 1);"
\ No newline at end of file
yield f"static constexpr {name}__oo<> {name} {{}};"
yield f"static_assert(sizeof {name} == 1);"
\ No newline at end of file
......@@ -5,6 +5,7 @@ from typing import Iterable
from transpiler.phases.emit_cpp.visitors import NodeVisitor, CoroutineMode, join
from transpiler.phases.typing.scope import Scope
from transpiler.phases.typing.types import ClassTypeType
from transpiler.phases.utils import make_lnd
from transpiler.utils import linenodata
......@@ -121,6 +122,22 @@ class ExpressionVisitor(NodeVisitor):
yield ")"
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)
# sync : call_sync(f, args)
if self.generator != CoroutineMode.SYNC:
......@@ -280,9 +297,9 @@ class ExpressionVisitor(NodeVisitor):
yield "{}"
def visit_Subscript(self, node: ast.Subscript) -> Iterable[str]:
# if isinstance(node.type, TypeType) and isinstance(node.type.type_object, MonomorphizedUserType):
# yield node.type.type_object.name
# return
if isinstance(node.type, ClassTypeType):
yield from self.visit_BaseType(node.type.inner_type)
return
yield "("
yield from self.visit(node.value)
yield ")["
......
......@@ -26,9 +26,14 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]:
yield "->"
yield rty
yield " {"
for rd in func.block_data.scope.root_decls:
pass
for var, initval in func.block_data.scope.root_decls.items():
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)
if not getattr(func.block_data.scope, "has_return", False):
if mode == CoroutineMode.SYNC:
yield "return"
else:
......@@ -47,7 +52,7 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]:
yield"decltype(sync("
yield from join(",", (arg.arg for arg in func.block_data.node.args.args))
yield "))"
yield ")"
yield ">"
rty_code = " ".join(task_type())
else:
pass
......@@ -293,6 +298,8 @@ class BlockVisitor(NodeVisitor):
yield "return "
if node.value:
yield from self.expr().visit(node.value)
else:
yield "typon::TyNone{}"
yield ";"
import ast
from typing import Iterable
from transpiler.phases.emit_cpp.class_ import emit_class
......@@ -9,7 +10,19 @@ from transpiler.phases.typing.types import CallableInstanceType, ClassTypeType,
def emit_module(mod: ModuleType) -> Iterable[str]:
yield "#include <python/builtins.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 from incl_vars
yield "template <typename _Unused = void>"
yield f"struct {mod.name()}__oo : referencemodel::moduletype<{mod.name()}__oo<>>"
yield "{"
......@@ -18,13 +31,13 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
continue
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
match ty:
case CallableInstanceType():
ScoperExprVisitor(ty.block_data.scope).visit_function_call(ty, [TypeVariable() for _ in ty.parameters])
yield from emit_function(name, ty)
case ClassTypeType():
yield from emit_class(ty)
case ClassTypeType(inner_type):
yield from emit_class(name, inner_type)
case _:
raise NotImplementedError(f"Unsupported module item type {ty}")
......
......@@ -8,6 +8,9 @@ from transpiler.phases.typing.exceptions import UnresolvedTypeVariableError
from transpiler.phases.typing.types import BaseType
from transpiler.utils import UnsupportedNodeError, highlight
MAPPINGS = {
}
class UniversalVisitor:
def visit(self, node):
......@@ -51,8 +54,7 @@ class NodeVisitor(UniversalVisitor):
def fix_name(self, name: str) -> str:
if name.startswith("__") and name.endswith("__"):
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]:
node = node.resolve()
......@@ -63,11 +65,11 @@ class NodeVisitor(UniversalVisitor):
case types.TY_FLOAT:
yield "double"
case types.TY_BOOL:
yield "bool"
yield "decltype(typon::TyBool(true))"
case types.TY_NONE:
yield "typon::TyNone"
case types.TY_STR:
yield "typon::TyStr"
yield 'decltype(""_ps)'
case types.TypeVariable(name):
yield f"$VAR__{name}"
......@@ -77,12 +79,12 @@ class NodeVisitor(UniversalVisitor):
yield "<"
yield from join(",", map(self.visit, node.generic_args))
yield ">"
case types.TY_LIST:
yield "typon::TyList"
case types.TY_DICT:
yield "typon::TyDict"
case types.TY_SET:
yield "typon::TySet"
# case types.TY_LIST:
# yield "typon::TyList"
# case types.TY_DICT:
# yield "typon::TyDict"
# case types.TY_SET:
# yield "typon::TySet"
case types.TY_TASK:
yield "typon::Task"
case types.TY_JOIN:
......
......@@ -133,15 +133,20 @@ class ScoperExprVisitor(ScoperVisitor):
self.visit_function_call(init, [ftype.inner_type, *arguments])
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)):
if b is None:
if i >= ftype.optional_at:
continue
raise ArgumentCountMismatchError(ftype, arguments)
if a is None and ftype.is_variadic:
if a is None:
if ftype.is_variadic:
break
raise ArgumentCountMismatchError(ftype, arguments)
if not a.try_assign(b):
raise TypeMismatchError(a, b, TypeMismatchKind.DIFFERENT_TYPE)
......@@ -155,8 +160,10 @@ class ScoperExprVisitor(ScoperVisitor):
vis = ScoperBlockVisitor(scope)
for stmt in ftype.block_data.node.body:
vis.visit(stmt)
if not getattr(scope, "has_return", False):
vis.visit(ast.Return())
if not getattr(scope.function, "has_return", False):
stmt = ast.Return()
ftype.block_data.node.body.append(stmt)
vis.visit(stmt)
#ftype.generic_parent.cache_instance(ftype)
return ftype.return_type.resolve()
# if isinstance(ftype, TypeType):# and isinstance(ftype.type_object, UserType):
......@@ -226,7 +233,11 @@ class ScoperExprVisitor(ScoperVisitor):
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):
# attr = mdecl.type
# if getattr(attr, "is_python_func", False):
......
......@@ -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, \
create_builtin_type, ConcreteType, GenericInstanceType, TypeListType, TypeTupleType, GenericParameter, \
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
def visit_generic_item(
......@@ -65,6 +65,8 @@ def visit_generic_item(
assert b.try_assign(a)
# todo
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)
return new_output_type
output_type.constraints_ = []
......@@ -130,8 +132,14 @@ class StdlibVisitor(NodeVisitorSeq):
assert isinstance(existing.type, ClassTypeType)
NewType = existing.type.inner_type
else:
base_class = create_builtin_generic_type if node.type_params else create_builtin_type
NewType = base_class(node.name)
if node.type_params:
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)
def visit_nongeneric(scope: Scope, output: ResolvedConcreteType):
......
......@@ -233,6 +233,10 @@ class UniqueTypeMixin:
class BuiltinType(UniqueTypeMixin, ResolvedConcreteType):
pass
@dataclass(eq=False)
class UserType(BuiltinType):
pass
@dataclass
class SpecialConstantType[T](ConcreteType):
value: T
......@@ -312,9 +316,9 @@ class GenericConstraint:
right: ResolvedConcreteType
@dataclass(eq=False, init=False)
@dataclass(eq=False)
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)
def constraints(self, args: list[ConcreteType]) -> list[GenericConstraint]:
......@@ -325,6 +329,7 @@ class GenericType(BaseType):
raise NotImplementedError()
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.generic_args = args
res.generic_parent = self
......@@ -362,11 +367,15 @@ class BuiltinGenericType(UniqueTypeMixin, GenericType):
return self.instantiate_(args)
def create_builtin_type(name: str):
class CreatedType(BuiltinType):
@dataclass(eq=False, init=False)
class UserGenericType(BuiltinGenericType):
pass
def create_builtin_type(name: str, prefix="Builtin", base=BuiltinType):
class CreatedType(base):
def name(self):
return name
CreatedType.__name__ = f"BuiltinType${name}"
CreatedType.__name__ = f"{prefix}Type${name}"
res = CreatedType()
return res
......@@ -387,11 +396,11 @@ def unimpl(*args, **kwargs):
raise NotImplementedError()
def create_builtin_generic_type(name: str):
class CreatedType(BuiltinGenericType):
def create_builtin_generic_type(name: str, prefix="Builtin", base=BuiltinGenericType):
class CreatedType(base):
def name(self):
return name
CreatedType.__name__ = f"BuiltinGenericType${name}"
CreatedType.__name__ = f"{prefix}GenericType${name}"
res = CreatedType()
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