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

Continue work

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