Commit 4136d4cf authored by Tom Niget's avatar Tom Niget

Fix module import and instantiation

parent 44114a7d
...@@ -12,27 +12,30 @@ ...@@ -12,27 +12,30 @@
// that this is a std::vector? // that this is a std::vector?
template <typename T> class PyList : public std::vector<T> { template <typename T> class PyList : public std::vector<T> {
public: 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()); return std::vector<T>(this->begin(), this->end());
} }
operator std::vector<T> &() { operator std::vector<T> &() {
return *reinterpret_cast<std::vector<T> *>(this); 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 { void py_repr(std::ostream &s) const {
s << '['; s << '[';
if (this->size() > 0) { if (_v->size() > 0) {
repr_to(this->operator[](0), s); repr_to(_v->operator[](0), s);
for (size_t i = 1; i < this->size(); i++) { for (size_t i = 1; i < _v->size(); i++) {
s << ", "; s << ", ";
repr_to(this->operator[](i), s); repr_to(_v->operator[](i), s);
} }
} }
s << ']'; s << ']';
...@@ -44,20 +47,23 @@ public: ...@@ -44,20 +47,23 @@ public:
PyList<T> operator+(const PyList<T> &other) const { PyList<T> operator+(const PyList<T> &other) const {
std::vector<T> v; std::vector<T> v;
v.reserve(this->size() + other.size()); v.reserve(_v->size() + other._v->size());
v.insert(v.end(), this->begin(), this->end()); v.insert(v.end(), _v->begin(), _v->end());
v.insert(v.end(), other.begin(), other.end()); v.insert(v.end(), other._v->begin(), other._v->end());
return PyList<T>(std::move(v)); return PyList<T>(std::move(v));
} }
PyList<T> operator*(size_t n) const { PyList<T> operator*(size_t n) const {
std::vector<T> v; PyList<T> v{};
v.reserve(this->size() * n); v._v->reserve(this->_v->size() * n);
for (size_t i = 0; i < n; i++) { 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) { template <typename T> PyList<T> list(std::initializer_list<T> &&v) {
......
...@@ -11,6 +11,14 @@ ...@@ -11,6 +11,14 @@
#include <typon/typon.hpp> #include <typon/typon.hpp>
#include "str.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> template <typename T>
concept Printable = requires(const T &x, std::ostream &s) { concept Printable = requires(const T &x, std::ostream &s) {
{ print_to(x, s) } -> std::same_as<void>; { print_to(x, s) } -> std::same_as<void>;
...@@ -21,14 +29,6 @@ concept Reprable = requires(const T &x, std::ostream &s) { ...@@ -21,14 +29,6 @@ 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>
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> 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
...@@ -45,6 +45,12 @@ void repr_to(const PyStr &x, std::ostream &s) { ...@@ -45,6 +45,12 @@ void repr_to(const PyStr &x, std::ostream &s) {
s << '"' << x << '"'; s << '"' << x << '"';
} }
template <Streamable T>
requires(Reprable<T>)
void print_to(const T &x, std::ostream &s) {
repr_to(x, s);
}
template <typename T> template <typename T>
concept PyPrint = requires(const T &x, std::ostream &s) { concept PyPrint = requires(const T &x, std::ostream &s) {
{ x.py_print(s) } -> std::same_as<void>; { x.py_print(s) } -> std::same_as<void>;
...@@ -72,6 +78,10 @@ template <Printable T> ...@@ -72,6 +78,10 @@ template <Printable 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 <> void print_to<PyStr>(const PyStr &x, std::ostream &s) {
s << x;
}
/* /*
template <Printable T, Printable... Args> template <Printable T, Printable... Args>
typon::Task<void> print(T const &head, Args const &...args) { typon::Task<void> print(T const &head, Args const &...args) {
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
using namespace std::literals; using namespace std::literals;
#include "print.hpp"
using PyStr = std::string; using PyStr = std::string;
template <typename T> PyStr str(const T &x) { template <typename T> PyStr str(const T &x) {
......
...@@ -13,7 +13,7 @@ struct sys_t { ...@@ -13,7 +13,7 @@ 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;
PyObj<PyList<PyStr>> argv; PyList<PyStr> argv;
} all; } all;
auto& get_all() { auto& get_all() {
......
...@@ -15,8 +15,15 @@ assert int.__add__ ...@@ -15,8 +15,15 @@ assert int.__add__
U = TypeVar("U") U = TypeVar("U")
V = TypeVar("V") 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: ... def __add__(self, other: Self) -> Self: ...
...@@ -27,6 +34,8 @@ class list(Generic[U]): ...@@ -27,6 +34,8 @@ class list(Generic[U]):
def pop(self, index: int = -1) -> U: ... def pop(self, index: int = -1) -> U: ...
assert(len(["a"]))
assert [1, 2, 3][1] assert [1, 2, 3][1]
......
# coding: utf-8 # coding: utf-8
from typon import is_cpp from typon import is_cpp
import sys as sis import sys as sis
from sys import stdout as truc from sys import stdout as truc
foo = 123 foo = 123
test = (2 + 3) * 4 test = (2 + 3) * 4
glob = 5 glob = 5
# def g(): # def g():
# a = 8 # a = 8
# if True: # if True:
# b = 9 # b = 9
# if True: # if True:
# c = 10 # c = 10
# if True: # if True:
# d = a + b + c # d = a + b + c
# if True: # if True:
# e = d + 1 # e = d + 1
# print(e) # print(e)
def f(x: int): def f(x: int):
return x + 1 return x + 1
def fct(param: int): def fct(param: int):
loc = f(456) loc = f(456)
global glob global glob
loc = 789 loc = 789
glob = 123 glob = 123
def fct2(): def fct2():
global glob global glob
glob += 5 glob += 5
if __name__ == "__main__": if __name__ == "__main__":
# todo: 0x55 & 7 == 5 # todo: 0x55 & 7 == 5
print(is_cpp) print(is_cpp)
# TODO: doesn't compile under G++ 12.2, fixed in trunk on March 15 # TODO: doesn't compile under G++ 12.2, fixed in trunk on March 15
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98056 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98056
print("C++ " if is_cpp() else "Python", print("C++ " if is_cpp() else "Python",
"res=", 5, ".", True, [4, 5, 6], {7, 8, 9}, [1, 2] + [3, 4], [5, 6] * 3, {1: 7, 9: 3}, 0x55 & 7 == 5, "res=", 5, ".", True, [4, 5, 6], {7, 8, 9}, [1, 2] + [3, 4], [5, 6] * 3, {1: 7, 9: 3}, 0x55 & 7 == 5,
3j) 3j)
print() print()
...@@ -6,4 +6,5 @@ BACKLOG = 1024 ...@@ -6,4 +6,5 @@ BACKLOG = 1024
PORT = 8000 PORT = 8000
if __name__ == "__main__": if __name__ == "__main__":
print(sys.argv) if len(sys.argv) > 2:
\ No newline at end of file print("Usage: webserver [ filepath ]")
\ No newline at end of file
...@@ -43,7 +43,7 @@ class BlockVisitor(NodeVisitor): ...@@ -43,7 +43,7 @@ class BlockVisitor(NodeVisitor):
from transpiler.phases.emit_cpp.function import FunctionVisitor from transpiler.phases.emit_cpp.function import FunctionVisitor
yield from FunctionVisitor(self.scope, CoroutineMode.TASK).emit_block(node.scope, block()) yield from FunctionVisitor(self.scope, CoroutineMode.TASK).emit_block(node.scope, block())
yield "int main(int argc, char* argv[]) {" 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 "root().call();"
yield "}" yield "}"
return return
......
...@@ -26,7 +26,7 @@ class ScoperBlockVisitor(ScoperVisitor): ...@@ -26,7 +26,7 @@ class ScoperBlockVisitor(ScoperVisitor):
self.scope.vars[alias.asname or alias.name] = dataclasses.replace(mod, kind=VarKind.LOCAL) self.scope.vars[alias.asname or alias.name] = dataclasses.replace(mod, kind=VarKind.LOCAL)
def visit_ImportFrom(self, node: ast.ImportFrom): 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: if not module:
raise NameError(node.module) raise NameError(node.module)
if not isinstance(module.type, ModuleType): if not isinstance(module.type, ModuleType):
......
...@@ -39,6 +39,11 @@ class StdlibVisitor(NodeVisitorSeq): ...@@ -39,6 +39,11 @@ class StdlibVisitor(NodeVisitorSeq):
pass pass
def visit_ClassDef(self, node: ast.ClassDef): 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 = [] typevars = []
for b in node.bases: for b in node.bases:
if isinstance(b, ast.Subscript) and isinstance(b.value, ast.Name) and b.value.id == "Generic": if isinstance(b, ast.Subscript) and isinstance(b.value, ast.Name) and b.value.id == "Generic":
...@@ -46,11 +51,10 @@ class StdlibVisitor(NodeVisitorSeq): ...@@ -46,11 +51,10 @@ class StdlibVisitor(NodeVisitorSeq):
typevars = [b.slice.id] typevars = [b.slice.id]
elif isinstance(b.slice, ast.Tuple): elif isinstance(b.slice, ast.Tuple):
typevars = [n.id for n in b.slice.value.elts] typevars = [n.id for n in b.slice.value.elts]
if existing := self.scope.get(node.name): else:
ty = existing.type parent = self.visit(b)
else: assert isinstance(parent, TypeType)
ty = TypeOperator([], node.name) ty.type_object.gen_parents.append(parent.type_object)
self.scope.vars[node.name] = VarDecl(VarKind.LOCAL, ty)
cl_scope = self.scope.child(ScopeKind.CLASS) cl_scope = self.scope.child(ScopeKind.CLASS)
visitor = StdlibVisitor(cl_scope, ty) visitor = StdlibVisitor(cl_scope, ty)
for var in typevars: for var in typevars:
......
...@@ -120,16 +120,19 @@ class TypeOperator(BaseType, ABC): ...@@ -120,16 +120,19 @@ class TypeOperator(BaseType, ABC):
variadic: bool = False variadic: bool = False
optional_at: Optional[int] = None optional_at: Optional[int] = None
gen_methods: ClassVar[Dict[str, GenMethodFactory]] = {} gen_methods: ClassVar[Dict[str, GenMethodFactory]] = {}
gen_parents: ClassVar[List[BaseType]] = []
def __init_subclass__(cls, **kwargs): def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs) super().__init_subclass__(**kwargs)
cls.gen_methods = {} cls.gen_methods = {}
cls.gen_parents = []
def __post_init__(self): def __post_init__(self):
if self.name is None: if self.name is None:
self.name = self.__class__.__name__ self.name = self.__class__.__name__
for name, factory in self.gen_methods.items(): for name, factory in self.gen_methods.items():
self.methods[name] = factory(self) self.methods[name] = factory(self)
self.parents.extend(self.gen_parents)
def unify_internal(self, other: BaseType): def unify_internal(self, other: BaseType):
if not isinstance(other, TypeOperator): if not isinstance(other, TypeOperator):
...@@ -209,6 +212,7 @@ class TypeOperator(BaseType, ABC): ...@@ -209,6 +212,7 @@ class TypeOperator(BaseType, ABC):
setattr(res, k.name, getattr(self, k.name)) setattr(res, k.name, getattr(self, k.name))
res.args = [arg.resolve().gen_sub(this, vardict, cache) for arg in self.args] 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.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 return res
def to_list(self) -> List["BaseType"]: 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