Commit 647b5c06 authored by Tom Niget's avatar Tom Niget

Continue work

parent 2e7eaeb0
......@@ -471,4 +471,26 @@ public:
using InterpGuard = py::scoped_interpreter;
#endif
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)>) {
return f.sync(std::forward<decltype(args)>(args)...);
} else {
return f(std::forward<decltype(args)>(args)...);
}
}*/
auto call_sync(auto f) {
if constexpr (HasSync<decltype(f)>) {
return [f](auto... args) { return f.sync(std::forward<decltype(args)>(args)...); };
} else {
return f;
}
}
#endif // TYPON_BUILTINS_HPP
......@@ -53,13 +53,13 @@ struct TyInt__oo : classtype<_Base0, TyInt__oo<>> {
struct : method {
auto operator()(auto self, auto other) const {
return dot(self, value) < dot(other, value);
return TyBool(dot(self, value) < dot(other, value));
}
} static constexpr oo__lt__oo{};
struct : method {
auto operator()(auto self, auto other) const {
return dot(self, value) > dot(other, value);
return (dot(self, value) > dot(other, value));
}
} static constexpr oo__gt__oo{};
......@@ -71,7 +71,7 @@ struct TyInt__oo : classtype<_Base0, TyInt__oo<>> {
struct : method {
auto operator()(auto self, auto other) const {
return dot(self, value) >= dot(other, value);
return TyBool(dot(self, value) >= dot(other, value));
}
} static constexpr oo__ge__oo{};
......@@ -81,6 +81,12 @@ struct TyInt__oo : classtype<_Base0, TyInt__oo<>> {
}
} static constexpr oo__str__oo{};
struct : method {
auto operator()(auto self, auto other) const {
return TyBool(dot(self, value) == dot(other, value));
}
} static constexpr oo__eq__oo{};
static constexpr auto oo__repr__oo = oo__str__oo;
struct Obj : value<TyInt__oo<>, Obj> {
......
......@@ -1071,6 +1071,20 @@ namespace meta {
} \
}
#define SIMPLE_OP(OP, DUNDER) \
namespace meta { \
template <typename Left, typename Right> \
concept DUNDER##able = requires(Left left, Right right) { \
left->oo__##DUNDER##__oo(left, right); \
}; \
} \
template <meta::object Left, meta::object Right> \
requires meta::DUNDER \
##able<Left, Right> auto operator OP(Left &&left, Right &&right) { \
return dot(std::forward<Left>(left), \
oo__##DUNDER##__oo)(std::forward<Right>(right)); \
}
/*template <typename Left, typename Right>
concept LeftAddable = requires (Left left, Right right) {
left->oo__add__oo(left, right);
......@@ -1116,6 +1130,15 @@ LR_OP(&, and)
LR_OP(|, or)
LR_OP(^, xor)
// TODO: iadd...
SIMPLE_OP(<, lt)
SIMPLE_OP(<=, le)
SIMPLE_OP(==, eq)
SIMPLE_OP(!=, ne)
SIMPLE_OP(>, gt)
SIMPLE_OP(>=, ge)
} // namespace referencemodel
#endif // REFERENCEMODEL_H
from typing import Callable
class Task[T]:
pass
class Join[T]:
pass
class Forked[T]:
def get(self) -> T: ...
......
......@@ -49,8 +49,8 @@ if __name__ == "__main__":
"res=", 5, ".", True, [4, 5, 6],
#{7, 8, 9},
# #[1, 2] + [3, 4], [5, 6] * 3,
{1: 7, 9: 3},
# 0x55 & 7 == 5,
#{1: 7, 9: 3},
0x55 & 7 == 5,
# #3j,
sum,
# # a,
......
......@@ -121,7 +121,12 @@ class ExpressionVisitor(NodeVisitor):
yield ")"
def visit_Call(self, node: ast.Call) -> Iterable[str]:
# async : co_await f(args)
# sync : call_sync(f, args)
if self.generator != CoroutineMode.SYNC:
yield "co_await"
else:
yield "call_sync"
yield "("
yield from self.visit(node.func)
yield ")("
......
......@@ -11,20 +11,48 @@ from transpiler.phases.typing.types import CallableInstanceType, BaseType
def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]:
yield f"struct : referencemodel::function {{"
yield "typon::Task<typon::TyNone> operator()("
def emit_body(name: str, mode: CoroutineMode, rty):
yield "auto"
yield name
yield "("
def emit_arg(arg, ty):
yield "auto"
yield arg.arg
yield from join(",", (emit_arg(arg, ty) for arg, ty in zip(func.block_data.node.args.args, func.parameters)))
yield ") const {"
yield ") const"
if rty is not None:
yield "->"
yield rty
yield " {"
for rd in func.block_data.scope.root_decls:
pass
yield from BlockVisitor(func.block_data.scope, generator=CoroutineMode.TASK).visit(func.block_data.node.body)
yield "co_return {};"
yield from BlockVisitor(func.block_data.scope, generator=mode).visit(func.block_data.node.body)
if mode == CoroutineMode.SYNC:
yield "return"
else:
yield "co_return"
yield "{};"
yield "}"
rty = func.return_type.generic_args[0]
try:
rty_code = " ".join(NodeVisitor().visit_BaseType(func.return_type))
except:
yield from emit_body("sync", CoroutineMode.SYNC, None)
def task_type():
yield from NodeVisitor().visit_BaseType(func.return_type.generic_parent)
yield "<"
yield"decltype(sync("
yield from join(",", (arg.arg for arg in func.block_data.node.args.args))
yield "))"
yield ")"
rty_code = " ".join(task_type())
else:
pass
yield from emit_body("operator()", CoroutineMode.TASK, rty_code)
yield f"}} static constexpr {name} {{}};"
yield f"static_assert(sizeof {name} == 1);"
......
......@@ -83,6 +83,12 @@ class NodeVisitor(UniversalVisitor):
yield "typon::TyDict"
case types.TY_SET:
yield "typon::TySet"
case types.TY_TASK:
yield "typon::Task"
case types.TY_JOIN:
yield "typon::Join"
case types.TY_FORKED:
yield "typon::Forked"
case _:
raise NotImplementedError(node)
......
......@@ -5,8 +5,8 @@ import importlib
from dataclasses import dataclass
from transpiler.exceptions import CompileError
from transpiler.phases.typing.types import BaseType, TypeVariable, CallableInstanceType, TY_NONE, PromiseInstanceType, \
TupleInstanceType, RuntimeValue, PromiseKind
from transpiler.phases.typing.types import BaseType, TypeVariable, CallableInstanceType, TY_NONE, \
TupleInstanceType, RuntimeValue, PromiseKind, GenericInstanceType, TRANSPARENT_PROMISES, PROMISES
from transpiler.utils import highlight, linenodata
from transpiler.phases.typing.common import ScoperVisitor, is_builtin, DeclareInfo
from transpiler.phases.typing.expr import ScoperExprVisitor, DUNDER
......@@ -211,11 +211,13 @@ class ScoperBlockVisitor(ScoperVisitor):
ftype = fct.obj_type
assert isinstance(ftype, CallableInstanceType)
vtype = self.expr().visit(node.value) if node.value else TY_NONE
vtype.unify(ftype.return_type.deref()
if isinstance(ftype.return_type.resolve(), PromiseInstanceType)
else ftype.return_type)
ret = ftype.return_type.resolve()
if isinstance(ret, GenericInstanceType) and ret.generic_parent in PROMISES:
ret = ret.generic_args[0]
vtype.unify(ret)
self.scope.diverges = True
#fct.has_return = True
fct.has_return = True
def visit_Global(self, node: ast.Global):
for name in node.names:
......
......@@ -8,7 +8,8 @@ from transpiler.phases.typing.common import ScoperVisitor, is_builtin
from transpiler.phases.typing.exceptions import ArgumentCountMismatchError, TypeMismatchKind, TypeMismatchError
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, PromiseInstanceType
TypeVariable, TY_LAMBDA, TypeListType, MethodType, TY_TUPLE, GenericInstanceType, PROMISES, TRANSPARENT_PROMISES, \
TY_FORKED, TY_JOIN
from transpiler.phases.typing.scope import ScopeKind, VarDecl, VarKind
from transpiler.utils import linenodata
......@@ -112,13 +113,16 @@ class ScoperExprVisitor(ScoperVisitor):
rtype = self.visit_function_call(ftype, [self.visit(arg) for arg in node.args])
actual = rtype
node.is_await = False
if isinstance(actual, PromiseInstanceType): # and actual.kind != PromiseKind.GENERATOR: TODO
if isinstance(actual, GenericInstanceType) and actual.generic_parent in PROMISES:
node.is_await = True
actual = actual.value.resolve()
if actual.generic_parent in TRANSPARENT_PROMISES:
actual = actual.generic_args[0].resolve()
if self.scope.function and isinstance(actual, Promise) and actual.kind == PromiseKind.FORKED \
and isinstance(fty := self.scope.function.obj_type.return_type, Promise):
fty.kind = PromiseKind.JOIN
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
......@@ -151,6 +155,8 @@ 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())
#ftype.generic_parent.cache_instance(ftype)
return ftype.return_type.resolve()
# if isinstance(ftype, TypeType):# and isinstance(ftype.type_object, UserType):
......
......@@ -405,46 +405,54 @@ TY_SET = create_builtin_generic_type("set")
TY_DICT = create_builtin_generic_type("dict")
TY_TUPLE = create_builtin_generic_type("tuple")
@dataclass(eq=False)
class PromiseInstanceType(GenericInstanceType):
value: ConcreteType
def deref(self):
match self.generic_parent.kind:
case PromiseKind.TASK | PromiseKind.JOIN:
return self.value.deref()
case _:
return self
@dataclass(eq=False)
class PromiseType(UniqueTypeMixin, GenericType):
kind: PromiseKind
def name(self):
match self.kind:
case PromiseKind.TASK:
return "Task"
case PromiseKind.JOIN:
return "Join"
case PromiseKind.FUTURE:
return "Future"
case PromiseKind.FORKED:
return "Forked"
case PromiseKind.GENERATOR:
return "Generator"
def _instantiate(self, args: list[ConcreteType]) -> GenericInstanceType:
assert len(args) == 1
return PromiseInstanceType(args[0])
TY_TASK = PromiseType([GenericParameter("T")], PromiseKind.TASK)
TY_JOIN = PromiseType([GenericParameter("T")], PromiseKind.JOIN)
TY_FUTURE = PromiseType([GenericParameter("T")], PromiseKind.FUTURE)
TY_FORKED = PromiseType([GenericParameter("T")], PromiseKind.FORKED)
TY_GENERATOR = PromiseType([GenericParameter("T")], PromiseKind.GENERATOR)
# @dataclass(eq=False)
# class PromiseInstanceType(GenericInstanceType):
# value: ConcreteType
#
# def deref(self):
# match self.generic_parent.kind:
# case PromiseKind.TASK | PromiseKind.JOIN:
# return self.value.deref()
# case _:
# return self
#
# @dataclass(eq=False)
# class PromiseType(UniqueTypeMixin, GenericType):
# kind: PromiseKind
#
# def name(self):
# match self.kind:
# case PromiseKind.TASK:
# return "Task"
# case PromiseKind.JOIN:
# return "Join"
# case PromiseKind.FUTURE:
# return "Future"
# case PromiseKind.FORKED:
# return "Forked"
# case PromiseKind.GENERATOR:
# return "Generator"
#
# def _instantiate(self, args: list[ConcreteType]) -> GenericInstanceType:
# assert len(args) == 1
# return PromiseInstanceType(args[0])
# TY_TASK = PromiseType([GenericParameter("T")], PromiseKind.TASK)
# TY_JOIN = PromiseType([GenericParameter("T")], PromiseKind.JOIN)
# TY_FUTURE = PromiseType([GenericParameter("T")], PromiseKind.FUTURE)
# TY_FORKED = PromiseType([GenericParameter("T")], PromiseKind.FORKED)
# TY_GENERATOR = PromiseType([GenericParameter("T")], PromiseKind.GENERATOR)
TY_TASK = create_builtin_generic_type("Task")
TY_JOIN = create_builtin_generic_type("Join")
TY_FUTURE = create_builtin_generic_type("Future")
TY_FORKED = create_builtin_generic_type("Forked")
TY_GENERATOR = create_builtin_generic_type("Generator")
PROMISES = (TY_TASK, TY_JOIN, TY_FUTURE, TY_FORKED, TY_GENERATOR)
TRANSPARENT_PROMISES = (TY_TASK, TY_JOIN, TY_FUTURE)
TY_TUPLE.instantiate_ = lambda args: TupleInstanceType(args)
......
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