Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
typon
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Tom Niget
typon
Commits
a1965638
Commit
a1965638
authored
May 24, 2023
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix recursion and add proper discrimination of sync/async functions
parent
4ab42ab0
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
71 additions
and
49 deletions
+71
-49
rt/examples/fork.cpp
rt/examples/fork.cpp
+2
-1
rt/include/python/builtins.hpp
rt/include/python/builtins.hpp
+2
-8
rt/include/python/builtins/print.hpp
rt/include/python/builtins/print.hpp
+2
-7
trans/test_runner.py
trans/test_runner.py
+2
-0
trans/tests/naive_fibonacci_accelerated_fork.py
trans/tests/naive_fibonacci_accelerated_fork.py
+11
-11
trans/transpiler/phases/emit_cpp/block.py
trans/transpiler/phases/emit_cpp/block.py
+1
-1
trans/transpiler/phases/emit_cpp/expr.py
trans/transpiler/phases/emit_cpp/expr.py
+9
-8
trans/transpiler/phases/emit_cpp/function.py
trans/transpiler/phases/emit_cpp/function.py
+4
-4
trans/transpiler/phases/typing/block.py
trans/transpiler/phases/typing/block.py
+6
-5
trans/transpiler/phases/typing/expr.py
trans/transpiler/phases/typing/expr.py
+9
-3
trans/transpiler/phases/typing/types.py
trans/transpiler/phases/typing/types.py
+23
-1
No files found.
rt/examples/fork.cpp
View file @
a1965638
#include <typon/typon.hpp>
#include <typon/logger.hpp>
#include <python/builtins.hpp>
#include <typon/generator.hpp>
using
namespace
typon
;
...
...
rt/include/python/builtins.hpp
View file @
a1965638
...
...
@@ -52,16 +52,10 @@ concept PyNext = requires(T t) {
struct
{
template
<
PyNext
T
>
std
::
optional
<
typename
T
::
value_type
>
sync
(
T
&
t
,
std
::
optional
<
typename
T
::
value_type
>
def
=
std
::
nullopt
)
{
operator
()
(
T
&
t
,
std
::
optional
<
typename
T
::
value_type
>
def
=
std
::
nullopt
)
{
auto
opt
=
t
.
py_next
();
return
opt
?
opt
:
def
;
}
template
<
PyNext
T
>
auto
operator
()(
T
&
t
,
std
::
optional
<
typename
T
::
value_type
>
def
=
std
::
nullopt
)
->
typon
::
Task
<
decltype
(
sync
(
t
,
def
))
>
{
co_return
sync
(
t
,
def
);
}
}
next
;
template
<
typename
T
>
...
...
@@ -69,7 +63,7 @@ std::ostream &operator<<(std::ostream &os, std::optional<T> const &opt) {
return
opt
?
os
<<
opt
.
value
()
:
os
<<
"None"
;
}
typon
::
Task
<
bool
>
is_cpp
()
{
co_
return
true
;
}
bool
is_cpp
()
{
return
true
;
}
class
NoneType
{
public:
...
...
rt/include/python/builtins/print.hpp
View file @
a1965638
...
...
@@ -50,19 +50,14 @@ typon::Task<void> print(T const &head, Args const &...args) {
}*/
struct
{
void
sync
()
{
std
::
cout
<<
'\n'
;
}
void
operator
()
()
{
std
::
cout
<<
'\n'
;
}
template
<
Printable
T
,
Printable
...
Args
>
void
sync
(
T
const
&
head
,
Args
const
&
...
args
)
{
void
operator
()
(
T
const
&
head
,
Args
const
&
...
args
)
{
print_to
(
head
,
std
::
cout
);
(((
std
::
cout
<<
' '
),
print_to
(
args
,
std
::
cout
)),
...);
std
::
cout
<<
'\n'
;
}
template
<
Printable
...
Args
>
typon
::
Task
<
void
>
operator
()(
Args
const
&
...
args
)
{
co_return
sync
(
args
...);
}
}
print
;
//typon::Task<void> print() { std::cout << '\n'; co_return; }
#endif // TYPON_PRINT_HPP
trans/test_runner.py
View file @
a1965638
...
...
@@ -28,6 +28,8 @@ def run_tests():
]
if
alt
:
=
environ
.
get
(
"ALT_RUNNER"
):
commands
.
append
(
alt
.
format
(
name_bin
=
name_bin
,
name_cpp_posix
=
name_cpp
.
as_posix
()))
else
:
print
(
"no ALT_RUNNER"
)
for
cmd
in
commands
:
if
system
(
cmd
)
!=
0
:
print
(
f"Error running command:
{
cmd
}
"
)
...
...
trans/tests/naive_fibonacci_accelerated_fork.py
View file @
a1965638
...
...
@@ -7,17 +7,17 @@ def fibo(n: int) -> int:
b
=
fibo
(
n
-
2
)
return
a
+
b
def
parallel_fibo
(
n
:
int
)
->
int
:
if
n
<
2
:
return
n
if
n
<
25
:
a
=
fibo
(
n
-
1
)
b
=
fibo
(
n
-
2
)
return
a
+
b
x
=
fork
(
lambda
:
fibo
(
n
-
1
))
y
=
fork
(
lambda
:
fibo
(
n
-
2
))
sync
()
return
x
.
get
()
+
y
.
get
()
#
def parallel_fibo(n: int) -> int:
#
if n < 2:
#
return n
#
if n < 25:
#
a = fibo(n - 1)
#
b = fibo(n - 2)
#
return a + b
#
x = fork(lambda: fibo(n - 1))
#
y = fork(lambda: fibo(n - 2))
#
sync()
#
return x.get() + y.get()
if
__name__
==
"__main__"
:
...
...
trans/transpiler/phases/emit_cpp/block.py
View file @
a1965638
...
...
@@ -120,7 +120,7 @@ class BlockVisitor(NodeVisitor):
yield
"Join"
yield
f"<decltype(sync(
{
', '
.
join
(
names
)
}
))>"
yield
"{"
inner_scope
=
node
.
scope
inner_scope
=
node
.
inner_
scope
for
child
in
node
.
body
:
# Python uses module- and function- level scoping. Blocks, like conditionals and loops, do not form scopes
...
...
trans/transpiler/phases/emit_cpp/expr.py
View file @
a1965638
...
...
@@ -75,13 +75,14 @@ class ExpressionVisitor(NodeVisitor):
def
visit_Name
(
self
,
node
:
ast
.
Name
)
->
Iterable
[
str
]:
res
=
self
.
fix_name
(
node
.
id
)
if
False
and
(
decl
:
=
self
.
scope
.
get
(
res
)):
if
decl
.
kind
==
VarKind
.
SELF
:
res
=
"(*this)"
elif
decl
.
future
and
CoroutineMode
.
ASYNC
in
self
.
generator
:
res
=
f"
{
res
}
.get()"
if
decl
.
future
==
"future"
:
res
=
"co_await "
+
res
if
self
.
scope
.
function
and
(
decl
:
=
self
.
scope
.
get
(
res
))
and
decl
.
type
is
self
.
scope
.
function
.
obj_type
:
res
=
"(*this)"
#if decl.kind == VarKind.SELF:
# res = "(*this)"
#elif decl.future and CoroutineMode.ASYNC in self.generator:
# res = f"{res}.get()"
# if decl.future == "future":
# res = "co_await " + res
yield
res
def
visit_Compare
(
self
,
node
:
ast
.
Compare
)
->
Iterable
[
str
]:
...
...
@@ -125,7 +126,7 @@ class ExpressionVisitor(NodeVisitor):
yield
from
()
return
# TODO: precedence needed?
if
CoroutineMode
.
ASYNC
in
self
.
generator
:
if
CoroutineMode
.
ASYNC
in
self
.
generator
and
node
.
is_await
:
yield
"co_await "
node
.
in_await
=
True
elif
CoroutineMode
.
FAKE
in
self
.
generator
:
...
...
trans/transpiler/phases/emit_cpp/function.py
View file @
a1965638
...
...
@@ -28,7 +28,7 @@ class FunctionVisitor(BlockVisitor):
yield
f"for (auto
{
node
.
target
.
id
}
: "
yield
from
self
.
expr
().
visit
(
node
.
iter
)
yield
")"
yield
from
self
.
emit_block
(
node
.
scope
,
node
.
body
)
yield
from
self
.
emit_block
(
node
.
inner_
scope
,
node
.
body
)
if
node
.
orelse
:
raise
NotImplementedError
(
node
,
"orelse"
)
...
...
@@ -36,13 +36,13 @@ class FunctionVisitor(BlockVisitor):
yield
"if ("
yield
from
self
.
expr
().
visit
(
node
.
test
)
yield
")"
yield
from
self
.
emit_block
(
node
.
scope
,
node
.
body
)
yield
from
self
.
emit_block
(
node
.
inner_
scope
,
node
.
body
)
if
node
.
orelse
:
yield
"else "
if
isinstance
(
node
.
orelse
,
ast
.
If
):
yield
from
self
.
visit
(
node
.
orelse
)
else
:
yield
from
self
.
emit_block
(
node
.
orelse
.
scope
,
node
.
orelse
)
yield
from
self
.
emit_block
(
node
.
orelse
.
inner_
scope
,
node
.
orelse
)
def
visit_Return
(
self
,
node
:
ast
.
Return
)
->
Iterable
[
str
]:
if
CoroutineMode
.
ASYNC
in
self
.
generator
:
...
...
@@ -57,7 +57,7 @@ class FunctionVisitor(BlockVisitor):
yield
"while ("
yield
from
self
.
expr
().
visit
(
node
.
test
)
yield
")"
yield
from
self
.
emit_block
(
node
.
scope
,
node
.
body
)
yield
from
self
.
emit_block
(
node
.
inner_
scope
,
node
.
body
)
if
node
.
orelse
:
raise
NotImplementedError
(
node
,
"orelse"
)
...
...
trans/transpiler/phases/typing/block.py
View file @
a1965638
...
...
@@ -6,7 +6,8 @@ from transpiler.phases.typing.annotations import TypeAnnotationVisitor
from
transpiler.phases.typing.common
import
ScoperVisitor
from
transpiler.phases.typing.expr
import
ScoperExprVisitor
from
transpiler.phases.typing.scope
import
VarDecl
,
VarKind
,
ScopeKind
from
transpiler.phases.typing.types
import
BaseType
,
TypeVariable
,
FunctionType
,
IncompatibleTypesError
,
TY_MODULE
from
transpiler.phases.typing.types
import
BaseType
,
TypeVariable
,
FunctionType
,
IncompatibleTypesError
,
TY_MODULE
,
\
Promise
@
dataclass
...
...
@@ -74,13 +75,13 @@ class ScoperBlockVisitor(ScoperVisitor):
def
visit_FunctionDef
(
self
,
node
:
ast
.
FunctionDef
):
argtypes
=
[
self
.
visit_annotation
(
arg
.
annotation
)
for
arg
in
node
.
args
.
args
]
rtype
=
self
.
visit_annotation
(
node
.
returns
)
rtype
=
Promise
(
self
.
visit_annotation
(
node
.
returns
)
)
ftype
=
FunctionType
(
argtypes
,
rtype
)
self
.
scope
.
vars
[
node
.
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
ftype
)
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION
)
scope
.
obj_type
=
ftype
scope
.
function
=
scope
node
.
scope
=
scope
node
.
inner_
scope
=
scope
for
arg
,
ty
in
zip
(
node
.
args
.
args
,
argtypes
):
scope
.
vars
[
arg
.
arg
]
=
VarDecl
(
VarKind
.
LOCAL
,
ty
)
for
b
in
node
.
body
:
...
...
@@ -92,7 +93,7 @@ class ScoperBlockVisitor(ScoperVisitor):
def
visit_If
(
self
,
node
:
ast
.
If
):
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
scope
.
function
=
self
.
scope
.
function
node
.
scope
=
scope
node
.
inner_
scope
=
scope
visitor
=
ScoperBlockVisitor
(
scope
,
self
.
root_decls
)
for
b
in
node
.
body
:
visitor
.
visit
(
b
)
...
...
@@ -107,7 +108,7 @@ class ScoperBlockVisitor(ScoperVisitor):
ftype
=
fct
.
obj_type
assert
isinstance
(
ftype
,
FunctionType
)
vtype
=
self
.
expr
().
visit
(
node
.
value
)
if
node
.
value
else
None
vtype
.
unify
(
ftype
.
return_type
)
vtype
.
unify
(
ftype
.
return_type
.
return_type
if
isinstance
(
ftype
.
return_type
,
Promise
)
else
ftype
.
return_type
)
def
visit_Global
(
self
,
node
:
ast
.
Global
):
for
name
in
node
.
names
:
...
...
trans/transpiler/phases/typing/expr.py
View file @
a1965638
...
...
@@ -4,7 +4,7 @@ from typing import List
from
transpiler.phases.typing
import
ScopeKind
,
VarDecl
,
VarKind
from
transpiler.phases.typing.common
import
ScoperVisitor
from
transpiler.phases.typing.types
import
IncompatibleTypesError
,
BaseType
,
TupleType
,
TY_STR
,
TY_BOOL
,
TY_INT
,
\
TY_COMPLEX
,
TY_NONE
,
FunctionType
,
PyList
,
TypeVariable
,
PySet
,
TypeType
,
PyDict
TY_COMPLEX
,
TY_NONE
,
FunctionType
,
PyList
,
TypeVariable
,
PySet
,
TypeType
,
PyDict
,
Promise
DUNDER
=
{
ast
.
Eq
:
"eq"
,
...
...
@@ -73,7 +73,12 @@ class ScoperExprVisitor(ScoperVisitor):
def
visit_Call
(
self
,
node
:
ast
.
Call
)
->
BaseType
:
ftype
=
self
.
visit
(
node
.
func
)
return
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
])
if
isinstance
(
rtype
,
Promise
):
node
.
is_await
=
True
return
rtype
.
return_type
node
.
is_await
=
False
return
rtype
def
visit_function_call
(
self
,
ftype
:
BaseType
,
arguments
:
List
[
BaseType
]):
if
not
isinstance
(
ftype
,
FunctionType
):
...
...
@@ -93,7 +98,8 @@ class ScoperExprVisitor(ScoperVisitor):
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION
)
scope
.
obj_type
=
ftype
scope
.
function
=
scope
node
.
scope
=
scope
node
.
inner_scope
=
scope
node
.
body
.
scope
=
scope
for
arg
,
ty
in
zip
(
node
.
args
.
args
,
argtypes
):
scope
.
vars
[
arg
.
arg
]
=
VarDecl
(
VarKind
.
LOCAL
,
ty
)
decls
=
{}
...
...
trans/transpiler/phases/typing/types.py
View file @
a1965638
...
...
@@ -42,6 +42,16 @@ class BaseType(ABC):
def
to_list
(
self
)
->
List
[
"BaseType"
]:
return
[
self
]
class
MagicType
(
BaseType
):
def
unify_internal
(
self
,
other
:
"BaseType"
):
if
type
(
self
)
is
not
type
(
other
):
raise
IncompatibleTypesError
()
def
contains_internal
(
self
,
other
:
"BaseType"
)
->
bool
:
return
False
cur_var
=
0
...
...
@@ -68,7 +78,7 @@ class TypeVariable(BaseType):
self
.
resolved
=
other
def
contains_internal
(
self
,
other
:
BaseType
)
->
bool
:
return
self
is
other
return
self
.
resolve
()
is
other
.
resolve
()
def
gen_sub
(
self
,
this
:
"BaseType"
,
typevars
)
->
"Self"
:
if
match
:
=
typevars
.
get
(
self
.
name
):
...
...
@@ -134,6 +144,10 @@ class FunctionType(TypeOperator):
def
return_type
(
self
):
return
self
.
args
[
0
]
@
return_type
.
setter
def
return_type
(
self
,
value
):
self
.
args
[
0
]
=
value
def
__str__
(
self
):
ret
,
*
args
=
map
(
str
,
self
.
args
)
if
self
.
variadic
:
...
...
@@ -214,3 +228,11 @@ class ForkResult(TypeOperator):
@
property
def
return_type
(
self
):
return
self
.
args
[
0
]
class
Promise
(
TypeOperator
):
def
__init__
(
self
,
args
:
BaseType
):
super
().
__init__
([
args
],
"Promise"
)
@
property
def
return_type
(
self
):
return
self
.
args
[
0
]
\ No newline at end of file
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