Commit 46594221 authored by Tom Niget's avatar Tom Niget

Fix module import and instantiation

parent 919cd141
......@@ -12,27 +12,30 @@
// that this is a std::vector?
template <typename T> class PyList : public std::vector<T> {
public:
PyList(std::vector<T> &&v) : std::vector<T>(std::move(v)) {}
PyList(std::shared_ptr<std::vector<T>> &&v) : _v(std::move(v)) {}
PyList(std::vector<T> &&v) : _v(std::move(std::make_shared<std::vector<T>>(std::move(v)))) {}
PyList(std::initializer_list<T> &&v) : std::vector<T>(std::move(v)) {}
PyList(std::initializer_list<T> &&v) : _v(std::make_shared<std::vector<T>>(std::move(v))) {}
operator std::vector<T>() const {
PyList() : _v(std::make_shared<std::vector<T>>()) {}
/*operator std::vector<T>() const {
return std::vector<T>(this->begin(), this->end());
}
operator std::vector<T> &() {
return *reinterpret_cast<std::vector<T> *>(this);
}
}*/
size_t py_len() const { return this->size(); }
size_t py_len() const { return _v->size(); }
void py_repr(std::ostream &s) const {
s << '[';
if (this->size() > 0) {
repr_to(this->operator[](0), s);
for (size_t i = 1; i < this->size(); i++) {
if (_v->size() > 0) {
repr_to(_v->operator[](0), s);
for (size_t i = 1; i < _v->size(); i++) {
s << ", ";
repr_to(this->operator[](i), s);
repr_to(_v->operator[](i), s);
}
}
s << ']';
......@@ -44,20 +47,23 @@ public:
PyList<T> operator+(const PyList<T> &other) const {
std::vector<T> v;
v.reserve(this->size() + other.size());
v.insert(v.end(), this->begin(), this->end());
v.insert(v.end(), other.begin(), other.end());
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 PyList<T>(std::move(v));
}
PyList<T> operator*(size_t n) const {
std::vector<T> v;
v.reserve(this->size() * n);
PyList<T> v{};
v._v->reserve(this->_v->size() * n);
for (size_t i = 0; i < n; i++) {
v.insert(v.end(), this->begin(), this->end());
v._v->insert(v._v->end(), this->_v->begin(), this->_v->end());
}
return PyList<T>(std::move(v));
return v;
}
private:
std::shared_ptr<std::vector<T>> _v;
};
template <typename T> PyList<T> list(std::initializer_list<T> &&v) {
......
......@@ -11,6 +11,14 @@
#include <typon/typon.hpp>
#include "str.hpp"
template <typename T>
concept Streamable = requires(const T &x, std::ostream &s) {
{ s << x } -> std::same_as<std::ostream &>;
};
template <Streamable T> void print_to(const T &x, std::ostream &s) { s << x; }
template <Streamable T> void repr_to(const T &x, std::ostream &s) { s << x; }
template <typename T>
concept Printable = requires(const T &x, std::ostream &s) {
{ print_to(x, s) } -> std::same_as<void>;
......@@ -21,14 +29,6 @@ concept Reprable = requires(const T &x, std::ostream &s) {
{ repr_to(x, s) } -> std::same_as<void>;
};
template <typename T>
concept Streamable = requires(const T &x, std::ostream &s) {
{ s << x } -> std::same_as<std::ostream &>;
};
template <Streamable T> void print_to(const T &x, std::ostream &s) { s << x; }
template <Streamable T> void repr_to(const T &x, std::ostream &s) { s << x; }
template <typename T>
concept FunctionPointer =
std::is_function_v<T> or std::is_member_function_pointer_v<T> or
......@@ -45,6 +45,12 @@ void repr_to(const PyStr &x, std::ostream &s) {
s << '"' << x << '"';
}
template <Streamable T>
requires(Reprable<T>)
void print_to(const T &x, std::ostream &s) {
repr_to(x, s);
}
template <typename T>
concept PyPrint = requires(const T &x, std::ostream &s) {
{ x.py_print(s) } -> std::same_as<void>;
......@@ -72,6 +78,10 @@ template <Printable T>
void repr_to(const std::shared_ptr<T> &x, std::ostream &s) {
repr_to(*x, s);
}
template <> void print_to<PyStr>(const PyStr &x, std::ostream &s) {
s << x;
}
/*
template <Printable T, Printable... Args>
typon::Task<void> print(T const &head, Args const &...args) {
......
......@@ -10,6 +10,8 @@
using namespace std::literals;
#include "print.hpp"
using PyStr = std::string;
template <typename T> PyStr str(const T &x) {
......
......@@ -13,7 +13,7 @@ struct sys_t {
static constexpr auto &stdin = std::cin;
static constexpr auto &stdout = std::cout;
static constexpr auto &stderr = std::cerr;
PyObj<PyList<PyStr>> argv;
PyList<PyStr> argv;
} all;
auto& get_all() {
......
......@@ -15,8 +15,15 @@ assert int.__add__
U = TypeVar("U")
V = TypeVar("V")
class HasLen:
def __len__(self) -> int: ...
def len(x: HasLen) -> int:
...
class list(Generic[U]):
class list(Generic[U], HasLen):
def __add__(self, other: Self) -> Self: ...
......@@ -27,6 +34,8 @@ class list(Generic[U]):
def pop(self, index: int = -1) -> U: ...
assert(len(["a"]))
assert [1, 2, 3][1]
......
......@@ -6,4 +6,5 @@ BACKLOG = 1024
PORT = 8000
if __name__ == "__main__":
print(sys.argv)
\ No newline at end of file
if len(sys.argv) > 2:
print("Usage: webserver [ filepath ]")
\ No newline at end of file
......@@ -43,7 +43,7 @@ class BlockVisitor(NodeVisitor):
from transpiler.phases.emit_cpp.function import FunctionVisitor
yield from FunctionVisitor(self.scope, CoroutineMode.TASK).emit_block(node.scope, block())
yield "int main(int argc, char* argv[]) {"
yield "py_sys::all.argv = pyobj<PyList<PyStr>>(std::vector<PyStr>(argv, argv + argc));"
yield "py_sys::all.argv = PyList<PyStr>(std::vector<PyStr>(argv, argv + argc));"
yield "root().call();"
yield "}"
return
......
......@@ -26,7 +26,7 @@ class ScoperBlockVisitor(ScoperVisitor):
self.scope.vars[alias.asname or alias.name] = dataclasses.replace(mod, kind=VarKind.LOCAL)
def visit_ImportFrom(self, node: ast.ImportFrom):
module = self.scope.get(node.module) # TODO: VarKind.MODULE ?
module = self.scope.get(node.module, VarKind.MODULE) # TODO: VarKind.MODULE ?
if not module:
raise NameError(node.module)
if not isinstance(module.type, ModuleType):
......
......@@ -39,6 +39,11 @@ class StdlibVisitor(NodeVisitorSeq):
pass
def visit_ClassDef(self, node: ast.ClassDef):
if existing := self.scope.get(node.name):
ty = existing.type
else:
ty = TypeType(TypeOperator([], node.name))
self.scope.vars[node.name] = VarDecl(VarKind.LOCAL, ty)
typevars = []
for b in node.bases:
if isinstance(b, ast.Subscript) and isinstance(b.value, ast.Name) and b.value.id == "Generic":
......@@ -46,11 +51,10 @@ class StdlibVisitor(NodeVisitorSeq):
typevars = [b.slice.id]
elif isinstance(b.slice, ast.Tuple):
typevars = [n.id for n in b.slice.value.elts]
if existing := self.scope.get(node.name):
ty = existing.type
else:
ty = TypeOperator([], node.name)
self.scope.vars[node.name] = VarDecl(VarKind.LOCAL, ty)
parent = self.visit(b)
assert isinstance(parent, TypeType)
ty.type_object.gen_parents.append(parent.type_object)
cl_scope = self.scope.child(ScopeKind.CLASS)
visitor = StdlibVisitor(cl_scope, ty)
for var in typevars:
......
......@@ -120,16 +120,19 @@ class TypeOperator(BaseType, ABC):
variadic: bool = False
optional_at: Optional[int] = None
gen_methods: ClassVar[Dict[str, GenMethodFactory]] = {}
gen_parents: ClassVar[List[BaseType]] = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.gen_methods = {}
cls.gen_parents = []
def __post_init__(self):
if self.name is None:
self.name = self.__class__.__name__
for name, factory in self.gen_methods.items():
self.methods[name] = factory(self)
self.parents.extend(self.gen_parents)
def unify_internal(self, other: BaseType):
if not isinstance(other, TypeOperator):
......@@ -209,6 +212,7 @@ class TypeOperator(BaseType, ABC):
setattr(res, k.name, getattr(self, k.name))
res.args = [arg.resolve().gen_sub(this, vardict, cache) for arg in self.args]
res.methods = {k: v.gen_sub(this, vardict, cache) for k, v in self.methods.items()}
res.parents = [p.gen_sub(this, vardict, cache) for p in self.parents]
return res
def to_list(self) -> List["BaseType"]:
......
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