Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
typon-compiler
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
typon
typon-compiler
Commits
1dddb1a8
Commit
1dddb1a8
authored
Mar 22, 2024
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix instance methods and start work on actors and mutexes
parent
3060d6c4
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
221 additions
and
32 deletions
+221
-32
typon/include/python/builtins.hpp
typon/include/python/builtins.hpp
+6
-0
typon/include/python/builtins/mutex.hpp
typon/include/python/builtins/mutex.hpp
+48
-0
typon/trans/stdlib/builtins_.py
typon/trans/stdlib/builtins_.py
+14
-1
typon/trans/tests/actors.py
typon/trans/tests/actors.py
+65
-0
typon/trans/tests/usertype.py
typon/trans/tests/usertype.py
+5
-4
typon/trans/transpiler/phases/emit_cpp/class_.py
typon/trans/transpiler/phases/emit_cpp/class_.py
+34
-16
typon/trans/transpiler/phases/emit_cpp/expr.py
typon/trans/transpiler/phases/emit_cpp/expr.py
+12
-1
typon/trans/transpiler/phases/emit_cpp/module.py
typon/trans/transpiler/phases/emit_cpp/module.py
+2
-1
typon/trans/transpiler/phases/emit_cpp/visitors.py
typon/trans/transpiler/phases/emit_cpp/visitors.py
+5
-1
typon/trans/transpiler/phases/typing/__init__.py
typon/trans/transpiler/phases/typing/__init__.py
+2
-1
typon/trans/transpiler/phases/typing/annotations.py
typon/trans/transpiler/phases/typing/annotations.py
+6
-0
typon/trans/transpiler/phases/typing/expr.py
typon/trans/transpiler/phases/typing/expr.py
+7
-5
typon/trans/transpiler/phases/typing/types.py
typon/trans/transpiler/phases/typing/types.py
+15
-2
No files found.
typon/include/python/builtins.hpp
View file @
1dddb1a8
...
...
@@ -140,6 +140,7 @@ static constexpr auto PyNone = std::nullopt;
#include "builtins/set.hpp"
#include "builtins/slice.hpp"
#include "builtins/str.hpp"
#include "builtins/mutex.hpp"
auto
is_cpp
()
{
return
typon
::
TyBool
(
true
);
}
...
...
@@ -414,6 +415,11 @@ template <auto IDX, typename T> auto constant_get(T &&val) {
return
dot
(
std
::
forward
<
T
>
(
val
),
oo__getitem__oo
)(
IDX
);
}
}
};
// namespace typon
#endif // TYPON_BUILTINS_HPP
typon/include/python/builtins/mutex.hpp
0 → 100644
View file @
1dddb1a8
#ifndef TYPON_MUTEX_HPP
#define TYPON_MUTEX_HPP
#include <ranges>
namespace
view
=
std
::
views
;
#include <python/basedef.hpp>
namespace
typon
{
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyMutex__oo
:
classtype
<
_Base0
,
TyMutex__oo
<>>
{
static
constexpr
std
::
string_view
name
=
"Mutex"
;
template
<
typename
T
>
struct
Obj
:
instance
<
TyMutex__oo
<>
,
Obj
<
T
>>
{
typon
::
Mutex
mutex
;
T
val
;
};
struct
:
method
{
auto
operator
()(
auto
self
,
auto
callback
)
->
typon
::
Task
<
TyNone
>
const
{
auto
lock
=
dot
(
self
,
mutex
).
lock
();
co_await
lock
;
co_await
callback
(
dot
(
self
,
val
));
co_return
{};
}
}
static
constexpr
when
{};
template
<
typename
T
>
auto
operator
()(
T
val
)
const
{
auto
obj
=
arc
(
Obj
<
T
>
());
dot
(
obj
,
val
)
=
val
;
return
obj
;
}
};
template
<
typename
T
>
using
ArcMutex
=
Arc
<
TyMutex__oo
<>::
template
Obj
<
T
>
>
;
}
static
constexpr
typon
::
TyMutex__oo
<>
Mutex
;
#endif // TYPON_MUTEX_HPP
typon/trans/stdlib/builtins_.py
View file @
1dddb1a8
...
...
@@ -215,4 +215,17 @@ def future[T](f: Callable[[], T]) -> Task[Future[T]]:
def
sync
()
->
None
:
# stub
pass
\ No newline at end of file
pass
class
Cell
[
T
]:
def
__init__
(
self
,
val
:
T
)
->
None
:
...
class
Mutex
[
T
]:
def
__init__
(
self
,
val
:
T
)
->
None
:
...
def
when
[
R
](
self
,
f
:
Callable
[[
Cell
[
T
]],
R
])
->
R
:
pass
assert
Cell
(
123
)
assert
Cell
(
"abc"
)
assert
Mutex
(
True
)
\ No newline at end of file
typon/trans/tests/actors.py
0 → 100644
View file @
1dddb1a8
# class Cell[T]:
# val: T
#
# class Mutex[T]:
# cell: Cell[T]
#
# def when[R](self, f: Callable[[Cell[T]], R]) -> R:
# pass
#
# def __enter__(self) -> Cell[T]:
# # locks then returns cell
# return self.cell
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# # unlocks
# pass
# @arc
class
Actor
[
T
]:
mutex
:
Mutex
[
T
]
def
__init__
(
self
,
val
:
T
):
self
.
mutex
=
Mutex
(
val
)
# def when(self, f: Callable[[T], object]):
# return future(lambda: self.mutex.when(f))
def
thing
(
x
):
print
(
"hello"
,
x
)
if
__name__
==
"__main__"
:
act
=
Actor
(
123
)
act
.
mutex
.
when
(
thing
)
# class Actor[T]:
# def __init__(self):
# self.fifo = []
# future(lambda: self.handle())
#
# def handle(self):
# while True:
# if self.fifo:
# f = self.fifo.pop(0)
# self.mutex.when(f)
# else:
# yield
#
# mutex: Mutex[T]
#
# def when(self, f: Callable[[T], object]):
# #return future(lambda: self.mutex.when(f))
# self.fifo.append(f)
#
#
#
# class A:
# def f(self): pass
#
# a = Actor[A]()
#
# a.when(A.f)
#
# b = Actor[int]()
typon/trans/tests/usertype.py
View file @
1dddb1a8
...
...
@@ -6,11 +6,12 @@ class Person:
age
:
int
def
__init__
(
self
,
name
,
age
):
print
(
"init"
)
self
.
name
=
name
self
.
age
=
age
def
afficher
(
self
):
print
(
self
.
name
,
self
.
age
)
print
(
"afficher"
,
self
.
name
,
self
.
age
)
# def creer():
# return Person("jean", 123)
...
...
@@ -19,8 +20,8 @@ if __name__ == "__main__":
y
=
Person
#x = creer()
x
=
Person
(
"jean"
,
123
)
print
(
x
.
name
)
print
(
x
.
age
)
print
(
"name"
,
x
.
name
)
print
(
"age"
,
x
.
age
)
x
.
afficher
()
#
y.afficher(x)
y
.
afficher
(
x
)
typon/trans/transpiler/phases/emit_cpp/class_.py
View file @
1dddb1a8
...
...
@@ -8,6 +8,7 @@ from transpiler.phases.typing.types import ConcreteType, TypeVariable, RuntimeVa
def
emit_class
(
name
:
str
,
node
:
ConcreteType
)
->
Iterable
[
str
]:
__TB_NODE__
=
node
.
block_data
.
node
yield
f"template <typename _Base0 = referencemodel::object>"
yield
f"struct
{
name
}
__oo : referencemodel::classtype<_Base0,
{
name
}
__oo<>> {{"
yield
f"static constexpr std::string_view name =
\
"
{
name
}\
"
;"
...
...
@@ -16,15 +17,22 @@ def emit_class(name: str, node: ConcreteType) -> Iterable[str]:
# for stmt in node.body:
# yield from inner.visit(stmt)
if
node
.
generic_parent
.
parameters
:
yield
"template<"
yield
from
join
(
","
,
(
f"typename
{
p
.
name
}
"
for
p
in
node
.
generic_parent
.
parameters
))
yield
">"
def
template_params
():
if
node
.
generic_parent
.
parameters
:
yield
from
(
p
.
name
for
p
in
node
.
generic_parent
.
parameters
)
else
:
yield
"_Void"
yield
"template<"
yield
from
join
(
","
,
(
f"typename
{
name
}
"
for
name
in
template_params
()))
yield
">"
yield
f"struct Obj : referencemodel::instance<
{
name
}
__oo<>, Obj"
yield
"<"
if
node
.
generic_parent
.
parameters
:
yield
"<"
yield
from
join
(
","
,
(
p
.
name
for
p
in
node
.
generic_parent
.
parameters
))
yield
">"
else
:
yield
"_Void"
yield
">"
yield
"> {"
for
mname
,
mdef
in
node
.
fields
.
items
():
...
...
@@ -37,10 +45,10 @@ def emit_class(name: str, node: ConcreteType) -> Iterable[str]:
# for stmt in node.body:
# yield from inner.visit(stmt)
yield
"template <typename... U>"
yield
"Obj(U&&... args) {"
yield
"dot(this, __init__)(this, std::forward<U>(args)...);"
yield
"}"
#
yield "template <typename... U>"
#
yield "Obj(U&&... args) {"
#
yield "dot(this, __init__)(this, std::forward<U>(args)...);"
#
yield "}"
yield
"};"
...
...
@@ -50,15 +58,25 @@ def emit_class(name: str, node: ConcreteType) -> Iterable[str]:
if
isinstance
(
mdef
.
val
,
ast
.
FunctionDef
):
gen_p
=
[
TypeVariable
(
p
.
name
,
emit_as_is
=
True
)
for
p
in
mdef
.
type
.
parameters
]
ty
=
mdef
.
type
.
instantiate
(
gen_p
)
ScoperExprVisitor
(
ty
.
block_data
.
scope
).
visit_function_call
(
ty
,
[
TypeVariable
(
)
for
_
in
ty
.
parameter
s
])
ScoperExprVisitor
(
ty
.
block_data
.
scope
).
visit_function_call
(
ty
,
[
TypeVariable
(
decltype_str
=
f"decltype(
{
arg
.
arg
}
)"
)
for
arg
in
ty
.
block_data
.
node
.
args
.
arg
s
])
yield
from
emit_function
(
mname
,
ty
,
"method"
)
yield
"template <typename... T>"
yield
"auto operator() (T&&... args) const {"
yield
"return referencemodel::rc(Obj(std::forward<T>(args)...));"
yield
"template <"
yield
from
join
(
","
,
(
f"typename
{
name
}
"
for
name
in
template_params
()))
yield
", typename... $T"
yield
">"
def
obj_params
():
yield
from
join
(
","
,
template_params
())
yield
"auto operator() ($T&&... args) const -> typon::Task<decltype(referencemodel::rc(Obj<"
yield
from
obj_params
()
yield
">{}))> {"
yield
"auto obj = referencemodel::rc(Obj<"
yield
from
obj_params
()
yield
">{});"
yield
"co_await dot(obj, __init__)(std::forward<$T>(args)...);"
yield
"co_return obj;"
yield
"}"
yield
f"}};"
yield
f"static constexpr
{
name
}
__oo<>
{
name
}
{{}};"
yield
f"static_assert(sizeof
{
name
}
== 1);"
\ No newline at end of file
yield
f"static_assert(sizeof
{
name
}
== 1);"
typon/trans/transpiler/phases/emit_cpp/expr.py
View file @
1dddb1a8
...
...
@@ -178,7 +178,18 @@ class ExpressionVisitor(NodeVisitor):
else
:
yield
from
self
.
visit
(
node
.
func
)
yield
")("
yield
")"
if
isinstance
(
node
.
func
.
type
,
ClassTypeType
):
inner
=
node
.
func
.
type
.
inner_type
assert
inner
is
node
.
type
.
generic_parent
yield
".template operator()"
yield
"<"
yield
from
join
(
", "
,
(
self
.
visit
(
arg
)
for
arg
in
node
.
type
.
generic_args
))
yield
">"
yield
"("
yield
from
join
(
", "
,
map
(
self
.
visit
,
node
.
args
))
yield
")"
#raise NotImplementedError()
...
...
typon/trans/transpiler/phases/emit_cpp/module.py
View file @
1dddb1a8
...
...
@@ -44,7 +44,8 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
match
ty
:
case
CallableInstanceType
():
ty
.
generic_parent
.
instance_cache
=
[]
ScoperExprVisitor
(
ty
.
block_data
.
scope
).
visit_function_call
(
ty
,
[
TypeVariable
()
for
_
in
ty
.
parameters
])
ScoperExprVisitor
(
ty
.
block_data
.
scope
).
visit_function_call
(
ty
,
[
TypeVariable
(
decltype_str
=
arg
.
arg
)
for
arg
in
ty
.
block_data
.
node
.
args
.
args
])
yield
from
emit_function
(
name
,
ty
,
gen_p
=
gen_p
)
case
GenericInstanceType
()
if
isinstance
(
ty
.
generic_parent
,
UserGenericType
):
yield
from
emit_class
(
name
,
ty
)
...
...
typon/trans/transpiler/phases/emit_cpp/visitors.py
View file @
1dddb1a8
...
...
@@ -71,9 +71,11 @@ class NodeVisitor(UniversalVisitor):
yield
"typon::TyNone"
case
types
.
TY_STR
:
yield
'decltype(""_ps)'
case
types
.
TypeVariable
(
name
,
emit_as_is
=
em
):
case
types
.
TypeVariable
(
name
,
emit_as_is
=
em
,
decltype_str
=
dt
):
if
em
:
yield
name
elif
dt
:
yield
dt
else
:
raise
UnresolvedTypeVariableError
(
node
)
yield
f"$VAR__
{
name
}
"
...
...
@@ -96,6 +98,8 @@ class NodeVisitor(UniversalVisitor):
yield
"typon::Join"
case
types
.
TY_FORKED
:
yield
"typon::Forked"
case
types
.
TY_MUTEX
:
yield
"typon::ArcMutex"
case
_
:
raise
NotImplementedError
(
node
)
...
...
typon/trans/transpiler/phases/typing/__init__.py
View file @
1dddb1a8
...
...
@@ -2,7 +2,7 @@ from transpiler.phases.typing.common import PRELUDE
from
transpiler.phases.typing.scope
import
VarKind
,
VarDecl
from
transpiler.phases.typing.types
import
TY_TASK
,
TY_CALLABLE
,
TY_OPTIONAL
,
TY_CPP_TYPE
,
TY_BUILTIN_FEATURE
,
TY_TUPLE
,
\
TY_DICT
,
TY_SET
,
TY_LIST
,
TY_COMPLEX
,
TY_BYTES
,
TY_STR
,
TY_FLOAT
,
TY_INT
,
TY_BOOL
,
TY_OBJECT
,
TY_JOIN
,
TY_FUTURE
,
\
TY_FORKED
,
TY_GENERATOR
TY_FORKED
,
TY_GENERATOR
,
TY_MUTEX
prelude_vars
=
{
"object"
:
TY_OBJECT
,
...
...
@@ -23,6 +23,7 @@ prelude_vars = {
"Future"
:
TY_FUTURE
,
"Forked"
:
TY_FORKED
,
"Generator"
:
TY_GENERATOR
,
"Mutex"
:
TY_MUTEX
}
PRELUDE
.
vars
.
update
({
name
:
VarDecl
(
VarKind
.
LOCAL
,
ty
.
type_type
())
for
name
,
ty
in
prelude_vars
.
items
()})
...
...
typon/trans/transpiler/phases/typing/annotations.py
View file @
1dddb1a8
...
...
@@ -46,6 +46,12 @@ class TypeAnnotationVisitor(NodeVisitorSeq):
assert
isinstance
(
ty_op
,
GenericType
)
return
ty_op
.
instantiate
(
args
)
def
visit_Call
(
self
,
node
:
ast
.
Call
)
->
BaseType
:
if
orig
:
=
getattr
(
node
,
"orig_node"
,
None
):
if
isinstance
(
orig
,
ast
.
Subscript
):
return
self
.
visit_Subscript
(
orig
)
raise
NotImplementedError
()
def
visit_List
(
self
,
node
:
ast
.
List
)
->
BaseType
:
return
TypeListType
([
self
.
visit
(
elt
)
for
elt
in
node
.
elts
])
...
...
typon/trans/transpiler/phases/typing/expr.py
View file @
1dddb1a8
...
...
@@ -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
,
TypeTupleType
,
TupleInstanceType
TY_FORKED
,
TY_JOIN
,
TypeTupleType
,
TupleInstanceType
,
TY_TYPE
from
transpiler.phases.typing.scope
import
ScopeKind
,
VarDecl
,
VarKind
from
transpiler.utils
import
linenodata
...
...
@@ -142,9 +142,10 @@ class ScoperExprVisitor(ScoperVisitor):
def
visit_function_call
(
self
,
ftype
:
ResolvedConcreteType
,
arguments
:
List
[
BaseType
]):
ftype
=
ftype
.
deref
()
if
isinstance
(
ftype
,
ClassTypeType
):
init
=
self
.
visit_getattr
(
ftype
,
"__init__"
)
self
.
visit_function_call
(
init
,
[
ftype
.
inner_type
,
*
arguments
])
return
ftype
.
inner_type
ftype
=
ftype
.
inner_type
.
deref
()
init
=
self
.
visit_getattr
(
TY_TYPE
.
instantiate
([
ftype
]),
"__init__"
)
self
.
visit_function_call
(
init
,
[
ftype
,
*
arguments
])
return
ftype
# assert isinstance(ftype, CallableInstanceType) TODO
...
...
@@ -161,6 +162,7 @@ class ScoperExprVisitor(ScoperVisitor):
break
raise
ArgumentCountMismatchError
(
ftype
,
arguments
)
if
not
a
.
try_assign
(
b
):
a
.
try_assign
(
b
)
raise
TypeMismatchError
(
a
,
b
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
if
not
ftype
.
is_native
:
...
...
@@ -201,7 +203,7 @@ class ScoperExprVisitor(ScoperVisitor):
# return equivalent.return_type
def
visit_Lambda
(
self
,
node
:
ast
.
Lambda
)
->
BaseType
:
argtypes
=
[
TypeVariable
(
)
for
_
in
node
.
args
.
args
]
argtypes
=
[
TypeVariable
(
decltype_str
=
f"decltype(
{
arg
.
arg
}
)"
)
for
arg
in
node
.
args
.
args
]
rtype
=
TypeVariable
()
ftype
=
TY_LAMBDA
.
instantiate
([
TypeListType
(
argtypes
),
rtype
])
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION
)
...
...
typon/trans/transpiler/phases/typing/types.py
View file @
1dddb1a8
...
...
@@ -119,6 +119,7 @@ class TypeVariable(ConcreteType):
var_name
:
str
=
field
(
default_factory
=
lambda
:
next_var_id
())
resolved
:
Optional
[
ConcreteType
]
=
None
emit_as_is
:
bool
=
False
decltype_str
:
Optional
[
str
]
=
None
def
resolve
(
self
)
->
ConcreteType
:
if
self
.
resolved
is
None
:
...
...
@@ -143,8 +144,15 @@ class TypeVariable(ConcreteType):
if
other
.
contains
(
self
):
from
transpiler.phases.typing.exceptions
import
RecursiveTypeUnificationError
raise
RecursiveTypeUnificationError
(
self
,
other
)
self
.
resolved
=
other
if
isinstance
(
other
,
TypeVariable
)
and
self
.
decltype_str
!=
other
.
decltype_str
:
if
(
self
.
decltype_str
and
self
.
decltype_str
.
startswith
(
"decltype"
))
and
(
other
.
decltype_str
and
other
.
decltype_str
.
startswith
(
"decltype"
)):
pass
elif
(
self
.
decltype_str
and
self
.
decltype_str
.
startswith
(
"decltype"
)):
other
.
decltype_str
=
self
.
decltype_str
def
contains_internal
(
self
,
other
:
BaseType
)
->
bool
:
return
self
.
resolve
()
is
other
.
resolve
()
...
...
@@ -337,11 +345,12 @@ class GenericType(BaseType):
return
res
def
instantiate_default
(
self
)
->
GenericInstanceType
:
return
self
.
instantiate
([
TypeVariable
(
)
for
_
in
self
.
parameters
])
return
self
.
instantiate
([
TypeVariable
(
decltype_str
=
p
.
name
)
for
p
in
self
.
parameters
])
def
__str__
(
self
):
try
:
return
str
(
self
.
instantiate_default
())
default
=
self
.
instantiate_default
()
return
"<"
+
", "
.
join
(
str
(
arg
.
name
())
for
arg
in
default
.
generic_args
)
+
"> "
+
str
(
default
)
except
:
return
super
().
__str__
()
...
...
@@ -421,6 +430,9 @@ TY_SET = create_builtin_generic_type("set")
TY_DICT
=
create_builtin_generic_type
(
"dict"
)
TY_TUPLE
=
create_builtin_generic_type
(
"tuple"
)
TY_MUTEX
=
create_builtin_generic_type
(
"Mutex"
)
# @dataclass(eq=False)
# class PromiseInstanceType(GenericInstanceType):
# value: ConcreteType
...
...
@@ -576,6 +588,7 @@ class CallableInstanceType(GenericInstanceType, MethodType):
return
f"(
{
", "
.
join
(
map
(
str
,
self
.
parameters
+
([
"*args"
]
if
self
.
is_variadic
else
[])))
}
) ->
{
self
.
return_type
}
"
def
try_assign_internal
(
self
,
other
:
BaseType
)
->
bool
:
other
=
other
.
deref
()
if
not
isinstance
(
other
,
CallableInstanceType
):
return
False
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment