Commit ed9984de authored by Tom Niget's avatar Tom Niget

Webserver finally works

parent 048b6744
......@@ -70,13 +70,13 @@ class TyNone {};
template <typename T>
concept PyIterator = requires(T t) {
{ t.py_next() } -> std::same_as<std::optional<T>>;
};
{ t.py_next() } -> std::same_as<std::optional<T>>;
};
template <typename T>
concept PyIterable = requires(T t) {
{ t.py_iter() } -> PyIterator;
};
{ t.py_iter() } -> PyIterator;
};
template <PyIterable T, PyIterator U> U iter(const T &t) { return t.py_iter(); }
......@@ -98,14 +98,14 @@ auto len(const T &t) {
template <PyLen T> size_t len(const T &t) { return t.py_len(); }*/
template<typename T> auto len(T&& t) { return dot(std::forward<T>(t), oo__len__oo)(); }
template <typename T> auto len(T &&t) {
return dot(std::forward<T>(t), oo__len__oo)();
}
template <typename T>
concept PyNext = requires(T t) {
{
t.py_next()
} -> std::same_as<std::optional<typename T::value_type>>;
};
{ t.py_next() } -> std::same_as<std::optional<typename T::value_type>>;
};
struct {
template <PyNext T>
......@@ -131,6 +131,7 @@ static constexpr auto PyNone = std::nullopt;
// #include "builtins/complex.hpp"
#include "builtins/bool.hpp"
#include "builtins/bytes.hpp"
#include "builtins/dict.hpp"
#include "builtins/int.hpp"
#include "builtins/list.hpp"
......@@ -179,7 +180,7 @@ struct TyFile__oo : classtype<_Base0, TyFile__oo<>> {
Task<void> operator()(auto self) { co_await typon::io::fsync(self->fd); }
} static constexpr flush{};
struct Obj : value<TyStr__oo<>, Obj> {
struct Obj : instance<TyFile__oo<>, Obj> {
Obj(int fd = -1, size_t len = 0) : fd(fd), len(len) {}
Obj(const Obj &other) : fd(other.fd), len(other.len) {}
......@@ -249,7 +250,7 @@ typon::Task<typon::TyFile__oo<>::Obj> open(auto path, std::string_view mode) {
int fd = co_await typon::io::openat(AT_FDCWD, path_c, flags, 0666);
if (fd < 0) {
std::cerr << path << "," << flags << std::endl;
std::cerr << path_c << "," << flags << std::endl;
system_error(-fd, "openat()");
}
co_return typon::TyFile__oo<>::Obj(fd, len);
......@@ -270,8 +271,8 @@ template <typename Ref> struct lvalue_or_rvalue {
template <typename Arg>
constexpr lvalue_or_rvalue(Arg &&arg) noexcept : ref(std::move(arg)) {}
constexpr operator Ref &() const &noexcept { return ref; }
constexpr operator Ref &&() const &&noexcept { return std::move(ref); }
constexpr operator Ref &() const & noexcept { return ref; }
constexpr operator Ref &&() const && noexcept { return std::move(ref); }
constexpr Ref &operator*() const noexcept { return ref; }
constexpr Ref *operator->() const noexcept { return &ref; }
};
......@@ -386,8 +387,8 @@ using InterpGuard = py::scoped_interpreter;
template <typename T>
concept HasSync = requires(T t) {
{ t.sync() } -> std::same_as<T>;
};
{ t.sync() } -> std::same_as<T>;
};
/*auto call_sync(auto f, auto... args) {
if constexpr (HasSync<decltype(f)>) {
......
......@@ -5,6 +5,8 @@
#ifndef TYPON_BYTES_H
#define TYPON_BYTES_H
#include "str.hpp"
/*class TyStr;
class TyBytes : public std::string {
......@@ -35,6 +37,12 @@ struct TyBytes__oo : classtype<_Base0, TyBytes__oo<>> {
}
} static constexpr oo__add__oo{};
struct : method {
auto operator()(auto self, auto encoding) const {
return typon::TyStr(dot(self, value));
}
} static constexpr decode{};
struct Obj : value<TyBytes__oo<>, Obj> {
std::string value;
......
......@@ -11,7 +11,6 @@
using namespace std::literals;
#include "bytes.hpp"
#include "slice.hpp"
// #include <format>
#include <fmt/format.h>
......@@ -177,12 +176,34 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
auto operator()(auto self) const { return (self->value.size()); }
} static constexpr oo__len__oo{};
/*struct : method {
auto operator()(auto self, auto other) const {
auto pos = self->value.find(other->value);
return typon::TyInt(pos == std::string::npos ? -1 : pos);
}
} static constexpr oo__find__oo{};*/
// format
/*
METHOD_GEN((typename... T), TyStr, format, (Self self, T &&...args), {
return TyStr(fmt::format(fmt::runtime(self),
std::forward<T>(args)...));
})
*/
struct : method {
auto operator()(auto self, auto... args) const {
return Obj(fmt::format(fmt::runtime(self->value), args...));
}
} static constexpr format{};
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; }
operator std::string_view() const { return value; }
};
auto operator()(std::string value) const { return Obj(value); }
......
......@@ -147,10 +147,11 @@ concept instance = std::derived_from<
referencemodel::instance<typename unwrap_all<T>::type, unwrap_all<T>>>;
template <typename T>
concept classtype = !
instance<T> &&std::derived_from<
unwrap_all<T>, referencemodel::classtype<typename unwrap_all<T>::base,
typename unwrap_all<T>::type>>;
concept classtype =
!instance<T> &&
std::derived_from<unwrap_all<T>,
referencemodel::classtype<typename unwrap_all<T>::base,
typename unwrap_all<T>::type>>;
template <typename F>
concept function = std::derived_from<F, referencemodel::function>;
......@@ -200,8 +201,7 @@ template <typename T>
concept unwrapped = std::is_same_v<T, unwrap_one<T>>;
template <typename T>
concept wrapped = !
unwrapped<T>;
concept wrapped = !unwrapped<T>;
/* Meta-programming utilities: wrapped_by */
......@@ -773,8 +773,8 @@ template <meta::wrapped T> Ref(Ref<T> &&) -> Ref<meta::unwrap_all<T>>;
/* Equality */
template <typename T, typename U>
requires meta::wrapped<T> || meta::wrapped<U> bool
operator==(const T &t, const U &u) {
requires meta::wrapped<T> || meta::wrapped<U>
bool operator==(const T &t, const U &u) {
return t.operator->() == u.operator->();
}
......@@ -1045,17 +1045,17 @@ namespace meta {
namespace meta { \
template <typename Left, typename Right> \
concept Left##DUNDER##able = requires(Left left, Right right) { \
left->oo__##DUNDER##__oo(left, right); \
}; \
left->oo__##DUNDER##__oo(left, right); \
}; \
\
template <typename Left, typename Right> \
concept Right##DUNDER##able = requires(Left left, Right right) { \
right->oo__r##DUNDER##__oo(right, left); \
}; \
right->oo__r##DUNDER##__oo(right, left); \
}; \
template <typename Left, typename Right> \
concept Aug##DUNDER##able = requires(Left left, Right right) { \
left->oo__i##DUNDER##__oo(left, right); \
}; \
left->oo__i##DUNDER##__oo(left, right); \
}; \
\
template <typename Left, typename Right> \
concept DUNDER##able = \
......@@ -1079,7 +1079,8 @@ namespace meta {
} \
template <meta::object Left, meta::object Right> \
requires meta::NormalOrAug \
##DUNDER##able<Left, Right> auto operator OP##=(Left &&left, Right &&right) { \
##DUNDER##able<Left, Right> auto operator OP##=(Left &&left, \
Right &&right) { \
if constexpr (meta::Aug##DUNDER##able<Left, Right>) { \
return dot(std::forward<Left>(left), \
oo__i##DUNDER##__oo)(std::forward<Right>(right)); \
......@@ -1092,8 +1093,8 @@ namespace meta {
namespace meta { \
template <typename Left, typename Right> \
concept DUNDER##able = requires(Left left, Right right) { \
left->oo__##DUNDER##__oo(left, right); \
}; \
left->oo__##DUNDER##__oo(left, right); \
}; \
} \
template <meta::object Left, meta::object Right> \
requires meta::DUNDER \
......@@ -1165,11 +1166,11 @@ concept DUNDERsetitemable =
requires(Left left, Right right) { left->oo__setitem__oo(left, right); };
} // namespace meta
/* 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));
}*/
/* 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
......
......@@ -91,6 +91,26 @@ struct socket__oo : referencemodel::moduletype<socket__oo<>> {
}
} static constexpr close{};
struct : referencemodel::method {
typon::Task<typon::TyBytes__oo<>::Obj> operator()(auto self,
int bufsize) const {
std::string buf(bufsize, '\0');
co_await typon::io::recv(self->fd, buf.data(), buf.size(), 0);
co_return typon::TyBytes(std::move(buf));
}
} static constexpr recv{};
struct : referencemodel::method {
typon::Task<typon::TyNone> operator()(auto self, auto data) const {
if (int sbytes = co_await typon::io::send(self->fd, data->value, 0);
sbytes < 0) {
co_await dot(self, close)();
system_error(-sbytes, "send()");
}
co_return {};
}
} static constexpr send{};
/*METHOD(typon::Task<void>, close, (Self self),
{ co_await typon::io::close(self->fd); })
......
......@@ -94,7 +94,7 @@ assert(len(["a"]))
#assert list.__getitem__
assert [].__getitem__
assert [4].__getitem__
assert [1, 2, 3][1]
assert [1, 2, 3].__getitem__(1)
class set[U]:
def __len__(self) -> int: ...
......@@ -122,7 +122,7 @@ def identity_2[U, V](x: U, y: V) -> tuple[U, V]:
...
assert list.__add__
assert list.__add__([5], [[6][0]])
assert list.__add__([5], [6])
assert list[int].__add__
assert identity_2(1, "a")
assert lambda x, y: identity_2(x, y)
......
......@@ -26,7 +26,7 @@ class socket:
def recv(self, bufsize: int) -> Task[bytes]:
pass
def send(self, data: bytes) -> Task[None]:
def send(self, data: str) -> Task[None]:
pass
def __init__(self, family: int, type: int) -> Self:
......
......@@ -26,7 +26,7 @@ def read_file(path):
def handle_connection(connfd, filepath):
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)
response_fmt = \
"HTTP/1.0 200 OK\r\n" \
......@@ -35,14 +35,14 @@ def handle_connection(connfd, filepath):
"\r\n" \
"{}"
response = response_fmt.format(len(content), content)
connfd.send(response.encode("utf-8"))
connfd.send(response)
connfd.close()
def server_loop(sockfd, filepath):
while True:
x = sockfd.accept()
connfd = sockfd.accept()[0]
#fork(lambda: handle_connection(connfd, filepath))
fork(lambda: handle_connection(connfd, filepath))
if __name__ == "__main__":
PORT = 8000
......
......@@ -9,7 +9,7 @@ class DesugarSubscript(ast.NodeTransformer):
def visit_Subscript(self, node: ast.Subscript):
match node.ctx:
case ast.Load():
return ast.Call(
res = ast.Call(
func=ast.Attribute(
value=node.value,
attr="__getitem__",
......@@ -22,4 +22,6 @@ class DesugarSubscript(ast.NodeTransformer):
case ast.Store(), ast.Del():
raise NotImplementedError("Subscript assignment and deletion not supported")
case _:
raise ValueError(f"Unexpected context {node.ctx!r}", linenodata(node))
\ No newline at end of file
raise ValueError(f"Unexpected context {node.ctx!r}", linenodata(node))
res.orig_node = node
return res
\ No newline at end of file
......@@ -5,7 +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.typing.types import ClassTypeType, TupleInstanceType
from transpiler.phases.utils import make_lnd
from transpiler.utils import linenodata
......@@ -300,11 +300,25 @@ class ExpressionVisitor(NodeVisitor):
if isinstance(node.type, ClassTypeType):
yield from self.visit_BaseType(node.type.inner_type)
return
yield "("
if isinstance(node.value.type, TupleInstanceType):
if not (isinstance(node.slice, ast.Constant) and isinstance(node.slice.value, int)):
raise NotImplementedError("Tuple subscript with non-constant not handled yet")
yield "std::get<"
yield str(node.slice.value)
yield ">("
yield from self.visit(node.value)
yield ")"
return
# yield "("
# yield from self.visit(node.value)
# yield ")["
# yield from self.visit(node.slice)
# yield "]"
yield "(co_await dot("
yield from self.visit(node.value)
yield ")["
yield ", oo__getitem__oo)("
yield from self.visit(node.slice)
yield "]"
yield "))"
def visit_UnaryOp(self, node: ast.UnaryOp) -> Iterable[str]:
yield from self.visit_unary_operation(node.op, node.operand)
......
......@@ -9,7 +9,7 @@ from transpiler.phases.typing.exceptions import ArgumentCountMismatchError, Type
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, \
TypeVariable, TY_LAMBDA, TypeListType, MethodType, TY_TUPLE, GenericInstanceType, PROMISES, TRANSPARENT_PROMISES, \
TY_FORKED, TY_JOIN
TY_FORKED, TY_JOIN, TypeTupleType, TupleInstanceType
from transpiler.phases.typing.scope import ScopeKind, VarDecl, VarKind
from transpiler.utils import linenodata
......@@ -38,7 +38,17 @@ DUNDER = {
}
class ScoperExprVisitor(ScoperVisitor):
def visit(self, node) -> BaseType:
def visit(self, node):
res = self.visit_inner(node)
if self.scope.function and isinstance(res, GenericInstanceType) and res.generic_parent is TY_FORKED:
fty = self.scope.function.obj_type.return_type
if fty.generic_parent in PROMISES:
fty = fty.generic_args[0] # todo: check if this whole if-block works
self.scope.function.obj_type.return_type = TY_JOIN.instantiate([fty])
return res
def visit_inner(self, node) -> BaseType:
if existing := getattr(node, "type", None):
return existing.resolve()
__TB_SKIP__ = True
......@@ -50,6 +60,8 @@ class ScoperExprVisitor(ScoperVisitor):
if True or not hasattr(res, "from_node"):
res.from_node = node
node.type = res
if orig := getattr(node, "orig_node", None):
orig.type = res
return res
def visit_Tuple(self, node: ast.Tuple) -> BaseType:
......@@ -108,6 +120,13 @@ class ScoperExprVisitor(ScoperVisitor):
return TY_BOOL
def visit_Call(self, node: ast.Call) -> BaseType:
if orig := getattr(node, "orig_node", None):
if isinstance(orig, ast.Subscript):
left = self.visit(orig.value)
if isinstance(left, TupleInstanceType):
if not (isinstance(orig.slice, ast.Constant) and isinstance(orig.slice.value, int)):
raise NotImplementedError("Tuple subscript with non-constant not handled yet")
return left.fields[orig.slice.value]
ftype = self.visit(node.func)
from transpiler.exceptions import CompileError
rtype = self.visit_function_call(ftype, [self.visit(arg) for arg in node.args])
......@@ -118,12 +137,6 @@ class ScoperExprVisitor(ScoperVisitor):
if actual.generic_parent in TRANSPARENT_PROMISES:
actual = actual.generic_args[0].resolve()
if self.scope.function and isinstance(actual, GenericInstanceType) and actual.generic_parent is TY_FORKED:
fty = self.scope.function.obj_type.return_type
if fty.generic_parent in PROMISES:
fty = fty.generic_args[0] # todo: check if this whole if-block works
self.scope.function.obj_type.return_type = TY_JOIN.instantiate([fty])
return actual
def visit_function_call(self, ftype: ResolvedConcreteType, arguments: List[BaseType]):
......@@ -304,9 +317,11 @@ class ScoperExprVisitor(ScoperVisitor):
left = self.visit(node.value)
if isinstance(left, ClassTypeType):
return self.anno().visit(node).type_type()
args = node.slice if type(node.slice) == tuple else [node.slice]
args = [self.visit(e) for e in args]
return self.make_dunder([left, *args], "getitem")
raise NotImplementedError("Should not happen")
# desugared
# args = node.slice if type(node.slice) == tuple else [node.slice]
# args = [self.visit(e) for e in args]
# return self.make_dunder([left, *args], "getitem")
def visit_UnaryOp(self, node: ast.UnaryOp) -> BaseType:
val = self.visit(node.operand)
......
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