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
8acf1377
Commit
8acf1377
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
72920c17
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
69 additions
and
48 deletions
+69
-48
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/include/python/builtins.hpp
View file @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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 @
8acf1377
...
...
@@ -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