Commit fe2492d6 authored by Tom Niget's avatar Tom Niget

webserver_eval works, many things work

parent 909e37a5
...@@ -65,8 +65,16 @@ namespace typon { ...@@ -65,8 +65,16 @@ namespace typon {
// class TyNone {}; // class TyNone {};
using TyNone = std::nullopt_t; //using TyNone = std::nullopt_t;
auto None = std::nullopt;
struct TyNone {
operator bool() const { return false; }
operator std::nullopt_t() const { return std::nullopt; }
template <typename T>
operator std::optional<T>() const { return std::nullopt; }
};
auto None = TyNone{};
} // namespace typon } // namespace typon
......
...@@ -173,21 +173,24 @@ struct TyDict__oo : classtype<_Base0, TyDict__oo<>> { ...@@ -173,21 +173,24 @@ struct TyDict__oo : classtype<_Base0, TyDict__oo<>> {
template <typename K, typename V> template <typename K, typename V>
struct Obj : instance<TyDict__oo<>, Obj<K, V>> { struct Obj : instance<TyDict__oo<>, Obj<K, V>> {
using map_type = std::unordered_map<K, V>;
std::shared_ptr<map_type> _m;
std::shared_ptr<std::unordered_map<K, V>> _m; /*Obj(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {}
Obj(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {}
Obj(std::unordered_map<K, V> &&m) Obj(std::unordered_map<K, V> &&m)
: _m(std::move( : _m(std::move(
std::make_shared<std::unordered_map<K, V>>(std::move(m)))) {} std::make_shared<std::unordered_map<K, V>>(std::move(m)))) {}*/
Obj(std::initializer_list<std::pair<K, V>> &&m) Obj(std::initializer_list<typename map_type::value_type> &&m)
: _m(std::make_shared<std::unordered_map<K, V>>(std::move(m))) {} : _m(std::make_shared<map_type>(std::move(m))) {}
Obj() : _m(std::make_shared<std::unordered_map<K, V>>()) {} Obj() : _m(std::make_shared<map_type>()) {}
template <typename... Args> template <typename... Args>
Obj(Args &&...args) Obj(Args &&...args)
: _m(std::make_shared<std::unordered_map<K, V>>( : _m(std::make_shared<map_type>(
std::forward<Args>(args)...)) {} std::forward<Args>(args)...)) {}
auto begin() const { return _m->begin(); }
auto end() const { return _m->end(); }
}; };
template <typename T> auto operator()(std::initializer_list<T> &&v) const { template <typename T> auto operator()(std::initializer_list<T> &&v) const {
......
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
namespace typon { namespace typon {
using namespace referencemodel; using namespace referencemodel;
struct UnpackedSlice {
ssize_t start, stop, step;
};
template <typename _Base0 = object> template <typename _Base0 = object>
struct TySlice__oo : classtype<_Base0, TySlice__oo<>> { struct TySlice__oo : classtype<_Base0, TySlice__oo<>> {
static constexpr std::string_view name = "TySlice"; static constexpr std::string_view name = "TySlice";
...@@ -25,6 +29,33 @@ struct TySlice__oo : classtype<_Base0, TySlice__oo<>> { ...@@ -25,6 +29,33 @@ struct TySlice__oo : classtype<_Base0, TySlice__oo<>> {
Obj(Start start, Stop stop, Step step) Obj(Start start, Stop stop, Step step)
: start(start), stop(stop), step(step) {} : start(start), stop(stop), step(step) {}
std::pair<ssize_t, UnpackedSlice> adjust_indices(ssize_t seq_length) {
UnpackedSlice res;
if constexpr (std::is_same_v<Step, TyNone>) {
res.step = 1;
} else {
res.step = this->step;
}
if constexpr (std::is_same_v<Start, TyNone>) {
res.start = res.step < 0 ? PY_SSIZE_T_MAX : 0;
} else {
res.start = this->start;
}
if constexpr (std::is_same_v<Stop, TyNone>) {
res.stop = res.step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX;
} else {
res.stop = this->stop;
}
auto len =
PySlice_AdjustIndices(seq_length, &res.start, &res.stop, res.step);
return {len, res};
}
}; };
template <typename Stop> auto operator()(Stop stop) const { template <typename Stop> auto operator()(Stop stop) const {
...@@ -64,36 +95,9 @@ static constexpr TySlice__oo<> TySlice{}; ...@@ -64,36 +95,9 @@ static constexpr TySlice__oo<> TySlice{};
std::optional<ssize_t> stop = 0; std::optional<ssize_t> stop = 0;
std::optional<ssize_t> step = 1; std::optional<ssize_t> step = 1;
struct UnpackedSlice {
ssize_t start, stop, step;
};
std::pair<ssize_t, UnpackedSlice> adjust_indices(ssize_t seq_length) {
UnpackedSlice res;
if (this->step == std::nullopt) {
res.step = 1;
} else {
res.step = this->step.value();
}
if (this->start == std::nullopt) {
res.start = res.step < 0 ? PY_SSIZE_T_MAX : 0;
} else {
res.start = this->start.value();
}
if (this->stop == std::nullopt) {
res.stop = res.step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX;
} else {
res.stop = this->stop.value();
}
auto len =
PySlice_AdjustIndices(seq_length, &res.start, &res.stop, res.step);
return {len, res};
}
};*/ };*/
#endif // TYPON_SLICE_HPP #endif // TYPON_SLICE_HPP
...@@ -178,6 +178,28 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> { ...@@ -178,6 +178,28 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
// getitem // getitem
struct : method { struct : method {
auto operator()(auto self, TySlice__oo<>::Obj<auto, auto, auto> slice) const {
auto [len, new_slice] = slice.adjust_indices(self->value.size());
Obj result;
result.value.reserve(len);
if (new_slice.start < new_slice.stop) {
if (new_slice.step > 0) {
for (auto i = new_slice.start; i < new_slice.stop;
i += new_slice.step) {
result.value.push_back(self->value[i]);
}
}
} else {
if (new_slice.step < 0) {
for (auto i = new_slice.start; i > new_slice.stop;
i += new_slice.step) {
result.value.push_back(self->value[i]);
}
}
}
return result;
}
auto operator()(auto self, auto index) const { auto operator()(auto self, auto index) const {
if (index < 0) { if (index < 0) {
index += self->value.size(); index += self->value.size();
...@@ -186,12 +208,24 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> { ...@@ -186,12 +208,24 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
} }
} static constexpr oo__getitem__oo{}; } static constexpr oo__getitem__oo{};
/*struct : method { struct : method {
auto operator()(auto self, auto other) const { auto operator()(auto self, auto other) const {
auto pos = self->value.find(other->value); auto pos = self->value.find(other->value);
return typon::TyInt(pos == std::string::npos ? -1 : pos); return (pos == std::string::npos ? -1 : pos);
} }
} static constexpr oo__find__oo{};*/ } static constexpr find{};
struct : method {
auto operator()(auto self, auto other) const {
return self->value.starts_with(other->value);
}
} static constexpr startswith{};
struct : method {
auto operator()(auto self, auto encoding = Obj(std::string("utf-8"))) const {
return Obj(self->value);
}
} static constexpr encode{};
// format // format
/* /*
...@@ -208,12 +242,19 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> { ...@@ -208,12 +242,19 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
} static constexpr format{}; } static constexpr format{};
struct Obj : value<TyStr__oo<>, Obj> { struct Obj : value<TyStr__oo<>, Obj> {
using value_type = std::string::value_type;
std::string value; std::string value;
constexpr Obj() : value() {} constexpr Obj() : value() {}
constexpr Obj(std::string value) : value(value) {} constexpr Obj(std::string value) : value(value) {}
constexpr Obj(const char* value, size_t count) : value(value, count) {}
operator std::string() const { return value; } operator std::string() const { return value; }
operator std::string_view() const { return value; } operator std::string_view() const { return value; }
auto data() const { return value.data(); }
auto size() const { return value.size(); }
bool operator ==(const Obj &other) const { return value == other.value; }
}; };
auto operator()(std::string value) const { return Obj(value); } auto operator()(std::string value) const { return Obj(value); }
...@@ -226,6 +267,12 @@ inline constexpr auto operator""_ps(const char *s, size_t len) noexcept { ...@@ -226,6 +267,12 @@ inline constexpr auto operator""_ps(const char *s, size_t len) noexcept {
return typon::TyStr__oo<>::Obj(std::string(s, len)); return typon::TyStr__oo<>::Obj(std::string(s, len));
} }
template <> struct std::hash<decltype(""_ps)> {
std::size_t operator()(const decltype(""_ps) &s) const noexcept {
return std::hash<std::string>()(s);
}
};
/*template <typename T> auto str(const T &x) { return dot(x, oo__str__oo)(); } /*template <typename T> auto str(const T &x) { return dot(x, oo__str__oo)(); }
template <typename T> template <typename T>
...@@ -264,4 +311,11 @@ template <typename T> auto repr(const T &x) { ...@@ -264,4 +311,11 @@ template <typename T> auto repr(const T &x) {
} }
} }
namespace PYBIND11_NAMESPACE {
namespace detail {
template<>
struct type_caster<decltype(""_ps)>
: string_caster<decltype(""_ps)> {};
}}
#endif // TYPON_STR_HPP #endif // TYPON_STR_HPP
Subproject commit 76287636438cf0a82701102ccb8014c66ea88506 Subproject commit f58767e045d32aaaed44c68082220e08c481c159
...@@ -49,7 +49,8 @@ class Iterable[U](Protocol): ...@@ -49,7 +49,8 @@ class Iterable[U](Protocol):
class str: class str:
def find(self, sub: Self) -> int: ... def find(self, sub: Self) -> int: ...
def format(self, *args) -> Self: ... def format(self, *args) -> Self: ...
def encode(self, encoding: Self) -> bytes: ... def encode(self, encoding: Self) -> Self: ... # TODO: bytes
def decode(self, encoding: Self) -> Self: ...
def __len__(self) -> int: ... def __len__(self) -> int: ...
def __add__(self, other: Self) -> Self: ... def __add__(self, other: Self) -> Self: ...
def __mul__(self, other: int) -> Self: ... def __mul__(self, other: int) -> Self: ...
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
import sys import sys
from socket import socket, SOCK_STREAM, AF_INET6, SOL_SOCKET, SO_REUSEADDR from socket import socket, SOCK_STREAM, AF_INET6, SOL_SOCKET, SO_REUSEADDR
from typon import fork from python.builtins import eval
from builtins import eval
#fork = lambda x: x() #fork = lambda x: x()
BACKLOG = 1024 BACKLOG = 1024
...@@ -25,21 +24,24 @@ def create_listening_socket(port): ...@@ -25,21 +24,24 @@ def create_listening_socket(port):
return sockfd return sockfd
def handle_connection(connfd): def handle_connection(connfd):
buf = connfd.recv(1024).decode("utf-8") buf: str = connfd.recv(1024).decode("utf-8")
resp: str resp: str
if not buf.startswith("GET /eval?e="): if not buf.startswith("GET /eval?e="):
resp = "Expression missing" resp = "Expression missing"
else: else:
http_pos = buf.find("HTTP/1.1\r\n") http_pos = buf.find("HTTP/1.1\r\n")
s = "str(" + buf[12:http_pos-1] + ")" s = "str(" + buf[12:http_pos-1] + ")"
resp = eval(s, {"req": buf}) #resp = eval(s, {"req": buf})
context = {"req": buf}
resp = eval(s, context)
response = response_fmt.format(len(resp), resp) response = response_fmt.format(len(resp), resp)
connfd.send(response.encode("utf-8")) connfd.send(response.encode("utf-8"))
connfd.close() connfd.close()
def server_loop(sockfd): def server_loop(sockfd):
while True: while True:
connfd, _ = sockfd.accept() #connfd, _ = sockfd.accept()
connfd = sockfd.accept()[0]
fork(lambda: handle_connection(connfd)) fork(lambda: handle_connection(connfd))
......
...@@ -345,19 +345,18 @@ class ExpressionVisitor(NodeVisitor): ...@@ -345,19 +345,18 @@ class ExpressionVisitor(NodeVisitor):
def visit_Dict(self, node: ast.Dict) -> Iterable[str]: def visit_Dict(self, node: ast.Dict) -> Iterable[str]:
def visit_item(key, value): def visit_item(key, value):
yield "std::pair {" yield "{"
yield from self.visit(key) yield from self.visit(key)
yield ", " yield ", "
yield from self.visit(value) yield from self.visit(value)
yield "}" yield "}"
if node.keys: if node.keys:
#yield from self.visit(node.type) yield from self.visit(node.type)
yield "typon::TyDict(" #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 "{}"
...@@ -394,8 +393,10 @@ class ExpressionVisitor(NodeVisitor): ...@@ -394,8 +393,10 @@ class ExpressionVisitor(NodeVisitor):
def visit_unary_operation(self, op, operand) -> Iterable[str]: def visit_unary_operation(self, op, operand) -> Iterable[str]:
if type(op) != str: if type(op) != str:
op = SYMBOLS[type(op)] op = SYMBOLS[type(op)]
yield "("
yield op yield op
yield from self.prec("unary").visit(operand) yield from self.visit(operand)
yield ")"
def visit_IfExp(self, node: ast.IfExp) -> Iterable[str]: def visit_IfExp(self, node: ast.IfExp) -> Iterable[str]:
yield "(" yield "("
......
...@@ -38,11 +38,16 @@ def emit_function(name: str, func: CallableInstanceType, base="function", gen_p= ...@@ -38,11 +38,16 @@ def emit_function(name: str, func: CallableInstanceType, base="function", gen_p=
yield rty yield rty
yield " {" yield " {"
for var, initval in func.block_data.scope.root_decls.items(): for var, initval in func.block_data.scope.root_decls.items():
__TB_NODE__ = initval
if isinstance(initval, BaseType):
yield from NodeVisitor().visit_BaseType(initval)
else:
yield "typename std::remove_reference<decltype(" # TODO: duplicate code in visit_lvalue yield "typename std::remove_reference<decltype(" # TODO: duplicate code in visit_lvalue
yield from ExpressionVisitor(func.block_data.scope, mode).visit(initval) yield from ExpressionVisitor(func.block_data.scope, mode).visit(initval)
yield ")>::type" yield ")>::type"
yield var yield var
yield ";" yield ";"
__TB_NODE__ = func.block_data.node
vis = BlockVisitor(func.block_data.scope, generator=mode) vis = BlockVisitor(func.block_data.scope, generator=mode)
for stmt in func.block_data.node.body: for stmt in func.block_data.node.body:
yield from vis.visit(stmt) yield from vis.visit(stmt)
......
...@@ -2,11 +2,13 @@ import ast ...@@ -2,11 +2,13 @@ import ast
from typing import Iterable from typing import Iterable
from transpiler.phases.emit_cpp.class_ import emit_class from transpiler.phases.emit_cpp.class_ import emit_class
from transpiler.phases.emit_cpp.function import emit_function from transpiler.phases.emit_cpp.expr import ExpressionVisitor
from transpiler.phases.emit_cpp.visitors import NodeVisitor from transpiler.phases.emit_cpp.function import emit_function, BlockVisitor
from transpiler.phases.emit_cpp.visitors import NodeVisitor, CoroutineMode
from transpiler.phases.typing.modules import ModuleType, TyponModuleType, PythonModuleType from transpiler.phases.typing.modules import ModuleType, TyponModuleType, PythonModuleType
from transpiler.phases.typing.types import CallableInstanceType, ClassTypeType, TypeVariable, BaseType, GenericType, \ from transpiler.phases.typing.types import CallableInstanceType, ClassTypeType, TypeVariable, BaseType, GenericType, \
GenericInstanceType, UserGenericType GenericInstanceType, UserGenericType, RuntimeValue
from transpiler.utils import linenodata
def emit_module(mod: ModuleType) -> Iterable[str]: def emit_module(mod: ModuleType) -> Iterable[str]:
...@@ -24,7 +26,7 @@ def emit_module(mod: ModuleType) -> Iterable[str]: ...@@ -24,7 +26,7 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
case TyponModuleType(): case TyponModuleType():
yield f"#include <python/{name}.hpp>" yield f"#include <python/{name}.hpp>"
case PythonModuleType(): case PythonModuleType():
yield f"namespace py_{name} {{" yield f"namespace py_python_{name} {{"
yield "template <typename _Unused = void>" yield "template <typename _Unused = void>"
yield f"struct {name}__oo : referencemodel::moduletype<{name}__oo<>> {{" yield f"struct {name}__oo : referencemodel::moduletype<{name}__oo<>> {{"
...@@ -75,25 +77,44 @@ def emit_module(mod: ModuleType) -> Iterable[str]: ...@@ -75,25 +77,44 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
case ast.Import(names): case ast.Import(names):
for alias in names: for alias in names:
yield from emit(alias.module_obj) yield from emit(alias.module_obj)
incl_vars.append(f"auto& {alias.asname or alias.name} = py_{alias.name}::all;") prefix = "python_" if isinstance(alias.module_obj, PythonModuleType) else ""
incl_vars.append(f"auto& {alias.asname or alias.name} = py_{prefix}{alias.module_obj.name()}::all;")
case ast.ImportFrom(module, names, _): case ast.ImportFrom(module, names, _):
yield from emit(node.module_obj) yield from emit(node.module_obj)
prefix = "python_" if isinstance(node.module_obj, PythonModuleType) else ""
for alias in names: for alias in names:
incl_vars.append(f"auto& {alias.asname or alias.name} = py_{module}::all.{alias.name};") if isinstance(node.module_obj, PythonModuleType):
if isinstance(node.module_obj.fields[alias.name].type.resolve(), TypeVariable):
continue # unused function
incl_vars.append(f"auto& {alias.asname or alias.name} = py_{prefix}{node.module_obj.name()}::all.{alias.name};")
yield "namespace PROGRAMNS {" yield "namespace PROGRAMNS {"
yield from incl_vars yield from incl_vars
yield "template <typename _Unused = void>" yield "template <typename _Unused = void>"
yield f"struct {mod.name()}__oo : referencemodel::moduletype<{mod.name()}__oo<>>" yield f"struct {mod.name()}__oo : referencemodel::moduletype<{mod.name()}__oo<>>"
yield "{" yield "{"
init_lines = []
for name, field in mod.fields.items(): for name, field in mod.fields.items():
if not field.in_class_def: if not field.in_class_def:
continue continue
if isinstance(field.type, ClassTypeType):
ty = field.type.inner_type
else:
ty = field.type ty = field.type
if isinstance(field.from_node, ast.Assign):
yield "static inline"
yield from NodeVisitor().visit_BaseType(field.from_node.value.type)
yield name
yield "="
yield from ExpressionVisitor(mod.block_data.scope, CoroutineMode.SYNC).visit(field.from_node.value)
yield ";"
# if not isinstance(field.from_node.value, RuntimeValue):
# assign_node = ast.Assign([ast.Name(name)], field.from_node.value, None, **linenodata(field.from_node))
# assign_node.is_declare = None
# init_lines.append(BlockVisitor(mod.block_data.scope).visit(assign_node))
continue
if isinstance(ty, ClassTypeType):
ty = ty.inner_type
gen_p = [TypeVariable(p.name, emit_as_is=True) for p in ty.parameters] gen_p = [TypeVariable(p.name, emit_as_is=True) for p in ty.parameters]
ty = ty.instantiate(gen_p) ty = ty.instantiate(gen_p)
from transpiler.phases.typing.expr import ScoperExprVisitor from transpiler.phases.typing.expr import ScoperExprVisitor
...@@ -109,7 +130,12 @@ def emit_module(mod: ModuleType) -> Iterable[str]: ...@@ -109,7 +130,12 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
case _: case _:
raise NotImplementedError(f"Unsupported module item type {ty}") raise NotImplementedError(f"Unsupported module item type {ty}")
yield f"{mod.name()}__oo() {{"
for line in init_lines:
yield from line
yield "}"
yield "};" yield "};"
yield f"constexpr {mod.name()}__oo<> {mod.name()};" yield f"{mod.name()}__oo<> {mod.name()};"
yield f"static_assert(sizeof {mod.name()} == 1);" yield f"static_assert(sizeof {mod.name()} == 1);"
yield "}" yield "}"
...@@ -73,6 +73,8 @@ class NodeVisitor(UniversalVisitor): ...@@ -73,6 +73,8 @@ class NodeVisitor(UniversalVisitor):
yield 'decltype(""_ps)' yield 'decltype(""_ps)'
case types.TY_LIST: case types.TY_LIST:
yield "typon::TyList__oo<>::Obj" yield "typon::TyList__oo<>::Obj"
case types.TY_DICT:
yield "typon::TyDict__oo<>::Obj"
case types.TypeVariable(name, emit_as_is=em, decltype_str=dt): case types.TypeVariable(name, emit_as_is=em, decltype_str=dt):
if em: if em:
yield name yield name
......
...@@ -115,8 +115,10 @@ class ScoperBlockVisitor(ScoperVisitor): ...@@ -115,8 +115,10 @@ class ScoperBlockVisitor(ScoperVisitor):
# return True # return True
val = val or RuntimeValue() val = val or RuntimeValue()
self.scope.function.vars[target.id] = VarDecl(VarKind.LOCAL, decl_val, val) 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.scope.function.root_decls[target.id] = val #if not isinstance(val, RuntimeValue):
if True:
self.scope.function.root_decls[target.id] = val if not isinstance(val, RuntimeValue) else decl_val
return False return False
return True return True
elif isinstance(target, ast.Tuple): elif isinstance(target, ast.Tuple):
......
...@@ -322,11 +322,14 @@ class ScoperExprVisitor(ScoperVisitor): ...@@ -322,11 +322,14 @@ class ScoperExprVisitor(ScoperVisitor):
def visit_Dict(self, node: ast.Dict) -> BaseType: def visit_Dict(self, node: ast.Dict) -> BaseType:
if not node.keys: if not node.keys:
return TY_DICT.instantiate_default() return TY_DICT.instantiate_default()
keys = [self.visit(e) for e in node.keys] key_type = TypeVariable()
values = [self.visit(e) for e in node.values] value_type = TypeVariable()
if len(set(keys)) != 1 or len(set(values)) != 1: for k, v in zip(node.keys, node.values):
raise NotImplementedError(f"Dict with different types not handled yet in `{ast.unparse(node)}`") if not key_type.try_assign(self.visit(k)):
return TY_DICT.instantiate([keys[0], values[0]]) raise NotImplementedError(f"Dict with different key types not handled yet in `{ast.unparse(node)}`")
if not value_type.try_assign(self.visit(v)):
raise NotImplementedError(f"Dict with different value types not handled yet in `{ast.unparse(node)}`")
return TY_DICT.instantiate([key_type, value_type])
def visit_Subscript(self, node: ast.Subscript) -> BaseType: def visit_Subscript(self, node: ast.Subscript) -> BaseType:
left = self.visit(node.value) left = self.visit(node.value)
......
...@@ -23,7 +23,7 @@ def make_module(name: str, scope: Scope) -> TyponModuleType: ...@@ -23,7 +23,7 @@ def make_module(name: str, scope: Scope) -> TyponModuleType:
return name return name
ty = CreatedType() ty = CreatedType()
for n, v in scope.vars.items(): for n, v in scope.vars.items():
ty.fields[n] = MemberDef(v.type, v.val, v.is_item_decl) ty.fields[n] = MemberDef(v.type, v.val, v.is_item_decl, v.from_node)
return ty return ty
visited_modules = {} visited_modules = {}
...@@ -62,6 +62,8 @@ def parse_module(mod_name: str, python_path: list[Path], scope=None, preprocess= ...@@ -62,6 +62,8 @@ def parse_module(mod_name: str, python_path: list[Path], scope=None, preprocess=
""" """
if mod_name.startswith("python."):
mod_name = mod_name[len("python."):]
try: try:
py_mod = importlib.import_module(mod_name) py_mod = importlib.import_module(mod_name)
except ModuleNotFoundError: except ModuleNotFoundError:
......
...@@ -29,6 +29,7 @@ class VarDecl: ...@@ -29,6 +29,7 @@ class VarDecl:
type: BaseType type: BaseType
val: Any = RuntimeValue() val: Any = RuntimeValue()
is_item_decl: bool = False is_item_decl: bool = False
from_node: ast.AST = None
class ScopeKind(Enum): class ScopeKind(Enum):
......
...@@ -102,7 +102,11 @@ class StdlibVisitor(NodeVisitorSeq): ...@@ -102,7 +102,11 @@ class StdlibVisitor(NodeVisitorSeq):
self.visit(stmt) self.visit(stmt)
def visit_Assign(self, node: ast.Assign): def visit_Assign(self, node: ast.Assign):
self.scope.vars[node.targets[0].id] = VarDecl(VarKind.LOCAL, self.anno().visit(node.value).type_type()) if self.is_native:
decl = VarDecl(VarKind.LOCAL, self.anno().visit(node.value).type_type())
else:
decl = VarDecl(VarKind.LOCAL, self.expr().visit(node.value), is_item_decl=True, from_node=node)
self.scope.vars[node.targets[0].id] = decl
def visit_AnnAssign(self, node: ast.AnnAssign): def visit_AnnAssign(self, node: ast.AnnAssign):
ty = self.anno().visit(node.annotation) ty = self.anno().visit(node.annotation)
......
...@@ -24,6 +24,7 @@ class MemberDef: ...@@ -24,6 +24,7 @@ class MemberDef:
type: "BaseType" type: "BaseType"
val: typing.Any = RuntimeValue() val: typing.Any = RuntimeValue()
in_class_def: bool = True in_class_def: bool = True
from_node: ast.AST = None
@dataclass @dataclass
class UnifyMode: class UnifyMode:
......
#include <python/builtins.hpp>
#include <python/socket.hpp>
#include <python/sys.hpp>
namespace py_python_builtins {
template <typename _Unused = void>
struct builtins__oo : referencemodel::moduletype<builtins__oo<>> {
struct : referencemodel::function {
auto
operator()(lvalue_or_rvalue<decltype(""_ps)> arg0,
lvalue_or_rvalue<
typon::TyDict__oo<>::Obj<decltype(""_ps), decltype(""_ps)>>
arg1) const {
InterpGuard guard{};
try {
return py::module_::import("builtins")
.attr("eval")(*arg0, *arg1)
.cast<decltype(""_ps)>();
} catch (py::error_already_set &e) {
std::cerr << "Python exception: " << e.what() << std::endl;
throw;
}
}
} static constexpr eval{};
};
builtins__oo<> all;
} // namespace py_python_builtins
namespace PROGRAMNS {
auto &sys = py_sys::all;
auto &socket = py_socket::all.socket;
auto &SOCK_STREAM = py_socket::all.SOCK_STREAM;
auto &AF_INET6 = py_socket::all.AF_INET6;
auto &SOL_SOCKET = py_socket::all.SOL_SOCKET;
auto &SO_REUSEADDR = py_socket::all.SO_REUSEADDR;
auto &eval = py_python_builtins::all.eval;
template <typename _Unused = void>
struct webserver_eval__oo : referencemodel::moduletype<webserver_eval__oo<>> {
static decltype(0_pi) BACKLOG;
static decltype(0_pi) PORT;
static decltype(""_ps) response_fmt;
struct : referencemodel::function {
template <typename AutoVar$9120453574589009546 = void,
typename AutoVar$return = void>
auto typon$$sync(AutoVar$9120453574589009546 port) const {
auto sockfd = call_sync(socket)(AF_INET6, SOCK_STREAM);
call_sync(dot((sockfd), setsockopt))(SOL_SOCKET, SO_REUSEADDR, 1_pi);
call_sync(dot((sockfd), bind))(std::make_tuple(""_ps, port));
call_sync(dot((sockfd), listen))(BACKLOG);
return sockfd;
}
using has_sync = std::true_type;
template <typename AutoVar$9120453574589009546 = void,
typename AutoVar$return = void>
auto operator()(AutoVar$9120453574589009546 port) const
-> typon::Task<decltype(typon$$sync(port))> {
auto sockfd = co_await (socket)(AF_INET6, SOCK_STREAM);
co_await (dot((sockfd), setsockopt))(SOL_SOCKET, SO_REUSEADDR, 1_pi);
co_await (dot((sockfd), bind))(std::make_tuple(""_ps, port));
co_await (dot((sockfd), listen))(BACKLOG);
co_return sockfd;
}
} static constexpr create_listening_socket{};
static_assert(HasSync<decltype(create_listening_socket)>);
static_assert(sizeof create_listening_socket == 1);
struct : referencemodel::function {
template <typename AutoVar$1818216228010231424 = void,
typename AutoVar$return = void>
auto operator()(AutoVar$1818216228010231424 connfd) const
-> typon::Task<typon::TyNone> {
auto buf = co_await (dot((co_await (dot((connfd), recv))(1024_pi)), decode))(
"utf-8"_ps);
if ((!co_await (dot((buf), startswith))("GET /eval?e="_ps))) {
auto resp = "Expression missing"_ps;
} else
{
auto http_pos = co_await (dot((buf), find))("HTTP/1.1\r\n"_ps);
auto s = ( (( ("str("_ps
+
( dot(buf, oo__getitem__oo)(
typon::TySlice(12_pi,
( (http_pos
-
1_pi)),
None)))))
+
")"_ps));
//auto resp = co_await (eval)(s, typon::TyDict({std::pair{"req"_ps, buf}}));
}
co_return None;
}
} static constexpr handle_connection{};
static_assert(sizeof handle_connection == 1);
struct : referencemodel::function {
template <typename AutoVar$1872507998259318362 = void,
typename AutoVar$return = void>
auto operator()(AutoVar$1872507998259318362 sockfd) const
-> typon::Join<typon::TyNone> {
while (typon::TyBool(true)) {
auto connfd = (co_await typon::constant_get<0>(
co_await (dot((sockfd), accept))()));
co_await typon::fork(handle_connection(connfd));
}
co_return None;
}
} static constexpr server_loop{};
static_assert(sizeof server_loop == 1);
struct : referencemodel::function {
template <typename AutoVar$return = void>
auto operator()() const -> typon::Task<typon::TyNone> {
co_await (print)("Serving on port"_ps, PORT);
co_await (print)();
auto sockfd = co_await (create_listening_socket)(PORT);
co_await (server_loop)(sockfd);
co_return None;
}
} static constexpr main{};
static_assert(sizeof main == 1);
webserver_eval__oo() {
BACKLOG = 1024_pi;
PORT = 8000_pi;
response_fmt =
"HTTP/1.0 200 OK\r\nContent-type: text/plain\r\nContent-length: {}\r\n\r\n{}"_ps;
}
};
webserver_eval__oo<> webserver_eval;
static_assert(sizeof webserver_eval == 1);
} // namespace PROGRAMNS
#ifdef TYPON_EXTENSION
#else
typon::Root root() { co_await dot(PROGRAMNS::webserver_eval, main)(); }
int main(int argc, char *argv[]) {
py_sys::all.argv = typon::TyList__oo<>::Obj(
std::vector<typon::TyStr__oo<>::Obj>(argv, argv + argc));
root().call();
}
#endif
\ No newline at end of file
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