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
d57706f4
Commit
d57706f4
authored
Aug 19, 2023
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rename type to py_type, add support for static members
parent
336e1080
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
346 additions
and
183 deletions
+346
-183
rt/include/python/basedef.hpp
rt/include/python/basedef.hpp
+1
-1
rt/include/python/builtins.hpp
rt/include/python/builtins.hpp
+8
-6
rt/include/python/builtins/exception.hpp
rt/include/python/builtins/exception.hpp
+24
-0
rt/include/python/builtins/print.hpp
rt/include/python/builtins/print.hpp
+17
-1
rt/include/python/builtins/str.hpp
rt/include/python/builtins/str.hpp
+9
-0
rt/include/python/hashlib.hpp
rt/include/python/hashlib.hpp
+4
-4
rt/include/python/os.hpp
rt/include/python/os.hpp
+8
-8
rt/include/python/socket.hpp
rt/include/python/socket.hpp
+6
-6
trans/stdlib/__init__.py
trans/stdlib/__init__.py
+14
-2
trans/stdlib/enum_.py
trans/stdlib/enum_.py
+3
-0
trans/tests/a_a_a_a_a_a_errtest.py
trans/tests/a_a_a_a_a_a_errtest.py
+29
-4
trans/tests/a_a_a_a_calcbasic.py
trans/tests/a_a_a_a_calcbasic.py
+126
-117
trans/tests/a_a_a_a_usertype.py
trans/tests/a_a_a_a_usertype.py
+0
-0
trans/tests/builtins_test.py
trans/tests/builtins_test.py
+4
-1
trans/transpiler/phases/emit_cpp/__init__.py
trans/transpiler/phases/emit_cpp/__init__.py
+8
-2
trans/transpiler/phases/emit_cpp/class_.py
trans/transpiler/phases/emit_cpp/class_.py
+11
-6
trans/transpiler/phases/emit_cpp/consts.py
trans/transpiler/phases/emit_cpp/consts.py
+2
-1
trans/transpiler/phases/emit_cpp/expr.py
trans/transpiler/phases/emit_cpp/expr.py
+9
-4
trans/transpiler/phases/emit_cpp/function.py
trans/transpiler/phases/emit_cpp/function.py
+1
-1
trans/transpiler/phases/emit_cpp/module.py
trans/transpiler/phases/emit_cpp/module.py
+4
-3
trans/transpiler/phases/typing/block.py
trans/transpiler/phases/typing/block.py
+23
-8
trans/transpiler/phases/typing/class_.py
trans/transpiler/phases/typing/class_.py
+8
-0
trans/transpiler/phases/typing/exceptions.py
trans/transpiler/phases/typing/exceptions.py
+2
-2
trans/transpiler/phases/typing/expr.py
trans/transpiler/phases/typing/expr.py
+13
-2
trans/transpiler/phases/typing/scope.py
trans/transpiler/phases/typing/scope.py
+12
-4
No files found.
rt/include/python/basedef.hpp
View file @
d57706f4
...
@@ -50,7 +50,7 @@ auto dot_bind(Obj, Attr attr) {
...
@@ -50,7 +50,7 @@ auto dot_bind(Obj, Attr attr) {
#define dot(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj, obj.NAME); }(OBJ)
#define dot(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj, obj.NAME); }(OBJ)
#define dotp(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj, obj->NAME); }(OBJ)
#define dotp(OBJ, NAME) [](auto && obj) -> auto { return dot_bind(obj, obj->NAME); }(OBJ)
#define dots(OBJ, NAME) [](auto && obj) -> auto { return std::remove_reference<decltype(obj)>::type::type::NAME; }(OBJ)
#define dots(OBJ, NAME) [](auto && obj) -> auto { return std::remove_reference<decltype(obj)>::type::
py_
type::NAME; }(OBJ)
#endif // TYPON_BASEDEF_HPP
#endif // TYPON_BASEDEF_HPP
rt/include/python/builtins.hpp
View file @
d57706f4
...
@@ -45,14 +45,14 @@ template <typename T>
...
@@ -45,14 +45,14 @@ template <typename T>
concept
PySmartPtr
=
requires
{
typename
T
::
element_type
;
};
concept
PySmartPtr
=
requires
{
typename
T
::
element_type
;
};
template
<
typename
T
>
template
<
typename
T
>
concept
PyUserType
=
requires
{
typename
T
::
type
;
};
concept
PyUserType
=
requires
{
typename
T
::
py_
type
;
};
template
<
typename
T
>
struct
RealType
{
template
<
typename
T
>
struct
RealType
{
using
type
=
T
;
using
type
=
T
;
};
};
template
<
PyUserType
T
>
struct
RealType
<
T
>
{
template
<
PyUserType
T
>
struct
RealType
<
T
>
{
using
type
=
typename
T
::
type
;
using
type
=
typename
T
::
py_
type
;
};
};
template
<
PySmartPtr
T
>
struct
RealType
<
T
>
{
template
<
PySmartPtr
T
>
struct
RealType
<
T
>
{
...
@@ -149,7 +149,7 @@ public:
...
@@ -149,7 +149,7 @@ public:
#include "builtins/str.hpp"
#include "builtins/str.hpp"
struct
file_s
{
struct
file_s
{
struct
type
{
struct
py_
type
{
METHOD
(
METHOD
(
typon
::
Task
<
PyStr
>
,
read
,
(
Self
self
,
size_t
size
=
-
1
),
{
typon
::
Task
<
PyStr
>
,
read
,
(
Self
self
,
size_t
size
=
-
1
),
{
if
(
size
==
-
1
)
{
if
(
size
==
-
1
)
{
...
@@ -178,9 +178,9 @@ struct file_s {
...
@@ -178,9 +178,9 @@ struct file_s {
typon
::
Task
<
void
>
,
flush
,
(
Self
self
),
typon
::
Task
<
void
>
,
flush
,
(
Self
self
),
{
co_await
typon
::
io
::
fsync
(
self
->
fd
);
})
{
co_await
typon
::
io
::
fsync
(
self
->
fd
);
})
type
(
int
fd
=
-
1
,
size_t
len
=
0
)
:
fd
(
fd
),
len
(
len
)
{}
py_
type
(
int
fd
=
-
1
,
size_t
len
=
0
)
:
fd
(
fd
),
len
(
len
)
{}
type
(
const
type
&
other
)
py_type
(
const
py_
type
&
other
)
:
fd
(
other
.
fd
),
len
(
other
.
len
)
{}
:
fd
(
other
.
fd
),
len
(
other
.
len
)
{}
METHOD
(
METHOD
(
...
@@ -198,7 +198,7 @@ struct file_s {
...
@@ -198,7 +198,7 @@ struct file_s {
}
file
;
}
file
;
namespace
typon
{
namespace
typon
{
using
PyFile
=
PyObj
<
decltype
(
file
)
::
type
>
;
using
PyFile
=
PyObj
<
decltype
(
file
)
::
py_
type
>
;
}
}
typon
::
Task
<
typon
::
PyFile
>
open
(
const
PyStr
&
path
,
std
::
string_view
mode
)
{
typon
::
Task
<
typon
::
PyFile
>
open
(
const
PyStr
&
path
,
std
::
string_view
mode
)
{
...
@@ -280,6 +280,8 @@ struct lvalue_or_rvalue {
...
@@ -280,6 +280,8 @@ struct lvalue_or_rvalue {
namespace
typon
{
namespace
typon
{
template
<
class
...
Types
>
template
<
class
...
Types
>
using
PyTuple
=
std
::
tuple
<
Types
...
>
;
using
PyTuple
=
std
::
tuple
<
Types
...
>
;
}
}
template
<
typename
T
>
template
<
typename
T
>
...
...
rt/include/python/builtins/exception.hpp
0 → 100644
View file @
d57706f4
//
// Created by Tom on 18/08/2023.
//
#ifndef TYPON_EXCEPTION_HPP
#define TYPON_EXCEPTION_HPP
#include "str.hpp"
struct
PyException_s
{
struct
py_type
{
PyStr
message
;
};
auto
operator
()(
const
PyStr
&
message
)
const
{
return
py_type
{
message
};
}
};
namespace
typon
{
using
PyException
=
PyObj
<
PyException_s
>
;
}
#endif // TYPON_EXCEPTION_HPP
rt/include/python/builtins/print.hpp
View file @
d57706f4
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
#include <iostream>
#include <iostream>
#include <ostream>
#include <ostream>
#include <functional>
#include "str.hpp"
#include "str.hpp"
#include <typon/typon.hpp>
#include <typon/typon.hpp>
...
@@ -56,6 +56,12 @@ void repr_to(const T &x, std::ostream &s) {
...
@@ -56,6 +56,12 @@ void repr_to(const T &x, std::ostream &s) {
s
<<
"<function at 0x"
<<
std
::
hex
<<
(
size_t
)
x
<<
std
::
dec
<<
">"
;
s
<<
"<function at 0x"
<<
std
::
hex
<<
(
size_t
)
x
<<
std
::
dec
<<
">"
;
}
}
template
<
typename
T
>
void
repr_to
(
const
std
::
function
<
T
>
&
x
,
std
::
ostream
&
s
)
{
s
<<
"<function at 0x"
<<
std
::
hex
<<
(
size_t
)
x
.
template
target
<
T
*
>()
<<
std
::
dec
<<
">"
;
}
template
<
>
void
repr_to
(
const
PyStr
&
x
,
std
::
ostream
&
s
)
{
template
<
>
void
repr_to
(
const
PyStr
&
x
,
std
::
ostream
&
s
)
{
s
<<
'"'
<<
x
<<
'"'
;
s
<<
'"'
<<
x
<<
'"'
;
}
}
...
@@ -96,4 +102,14 @@ struct {
...
@@ -96,4 +102,14 @@ struct {
}
}
}
print
;
}
print
;
// typon::Task<void> print() { std::cout << '\n'; co_return; }
// typon::Task<void> print() { std::cout << '\n'; co_return; }
struct
{
PyStr
operator
()(
const
PyStr
&
s
=
""
_ps
)
{
std
::
cout
<<
s
;
PyStr
input
;
std
::
getline
(
std
::
cin
,
input
);
return
input
;
}
}
input
;
#endif // TYPON_PRINT_HPP
#endif // TYPON_PRINT_HPP
rt/include/python/builtins/str.hpp
View file @
d57706f4
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
#include <sstream>
#include <sstream>
#include <string>
#include <string>
#include <algorithm>
using
namespace
std
::
literals
;
using
namespace
std
::
literals
;
...
@@ -47,6 +48,14 @@ public:
...
@@ -47,6 +48,14 @@ public:
return
pos
==
std
::
string
::
npos
?
-
1
:
pos
;
return
pos
==
std
::
string
::
npos
?
-
1
:
pos
;
})
})
METHOD
(
bool
,
isspace
,
(
Self
self
),
{
return
std
::
all_of
(
self
.
begin
(),
self
.
end
(),
isspace
);
})
METHOD
(
auto
,
py_contains
,
(
Self
self
,
const
std
::
string
&
x
),
{
return
self
.
std
::
string
::
find
(
x
)
!=
std
::
string
::
npos
;
})
PyStr
operator
[](
PySlice
slice
)
const
{
PyStr
operator
[](
PySlice
slice
)
const
{
auto
[
len
,
new_slice
]
=
slice
.
adjust_indices
(
this
->
size
());
auto
[
len
,
new_slice
]
=
slice
.
adjust_indices
(
this
->
size
());
...
...
rt/include/python/hashlib.hpp
View file @
d57706f4
...
@@ -20,16 +20,16 @@ struct hashlib_t {
...
@@ -20,16 +20,16 @@ struct hashlib_t {
typedef
int
(
*
openssl_final
)(
unsigned
char
*
md
,
void
*
context
);
typedef
int
(
*
openssl_final
)(
unsigned
char
*
md
,
void
*
context
);
struct
_Hash_s
{
struct
_Hash_s
{
struct
type
{
struct
py_
type
{
type
(
PyObj
<
void
>
context
,
openssl_update
update
,
openssl_final
final
,
py_
type
(
PyObj
<
void
>
context
,
openssl_update
update
,
openssl_final
final
,
int
diglen
)
int
diglen
)
:
_context
(
context
),
_update
(
update
),
_final
(
final
),
_diglen
(
diglen
)
{
:
_context
(
context
),
_update
(
update
),
_final
(
final
),
_diglen
(
diglen
)
{
}
}
type
()
{}
py_
type
()
{}
type
(
const
type
&
other
)
py_type
(
const
py_
type
&
other
)
:
_context
(
other
.
_context
),
_update
(
other
.
_update
),
:
_context
(
other
.
_context
),
_update
(
other
.
_update
),
_final
(
other
.
_final
),
_diglen
(
other
.
_diglen
)
{}
_final
(
other
.
_final
),
_diglen
(
other
.
_diglen
)
{}
...
...
rt/include/python/os.hpp
View file @
d57706f4
...
@@ -25,7 +25,7 @@ struct os_t {
...
@@ -25,7 +25,7 @@ struct os_t {
auto
,
fsdecode
,
(
std
::
string
s
)
{
return
s
;
})
auto
,
fsdecode
,
(
std
::
string
s
)
{
return
s
;
})
struct
Stat_Result_s
{
struct
Stat_Result_s
{
struct
type
{
struct
py_
type
{
int
st_mode
;
int
st_mode
;
unsigned
long
long
st_ino
;
unsigned
long
long
st_ino
;
dev_t
st_dev
;
dev_t
st_dev
;
...
@@ -45,14 +45,14 @@ struct os_t {
...
@@ -45,14 +45,14 @@ struct os_t {
}
Stat_Result
;
}
Stat_Result
;
struct
DirEntry_s
{
struct
DirEntry_s
{
struct
type
{
struct
py_
type
{
PyStr
name
;
PyStr
name
;
PyStr
path
;
PyStr
path
;
};
};
}
DirEntry
;
}
DirEntry
;
struct
_Scandiriterator_s
{
struct
_Scandiriterator_s
{
struct
type
{
struct
py_
type
{
using
value_type
=
PyObj
<
DirEntry_s
>
;
using
value_type
=
PyObj
<
DirEntry_s
>
;
using
reference
=
PyObj
<
DirEntry_s
>
;
using
reference
=
PyObj
<
DirEntry_s
>
;
...
@@ -65,14 +65,14 @@ struct os_t {
...
@@ -65,14 +65,14 @@ struct os_t {
METHOD
(
auto
,
begin
,
(
Self
self
),
{
return
*
self
;
})
METHOD
(
auto
,
begin
,
(
Self
self
),
{
return
*
self
;
})
METHOD
(
auto
,
end
,
(
Self
self
),
METHOD
(
auto
,
end
,
(
Self
self
),
{
return
type
(
self
->
basepath
,
self
->
namelist
,
self
->
n
,
self
->
n
);
})
{
return
py_
type
(
self
->
basepath
,
self
->
namelist
,
self
->
n
,
self
->
n
);
})
auto
operator
*
()
{
auto
operator
*
()
{
auto
name
=
PyStr
(
this
->
namelist
[
this
->
current
]
->
d_name
);
auto
name
=
PyStr
(
this
->
namelist
[
this
->
current
]
->
d_name
);
return
pyobj_agg
<
DirEntry_s
>
(
name
,
this
->
basepath
+
name
);
return
pyobj_agg
<
DirEntry_s
>
(
name
,
this
->
basepath
+
name
);
}
}
type
(
const
PyStr
&
basepath
,
struct
dirent
**
namelist
,
int
n
,
py_
type
(
const
PyStr
&
basepath
,
struct
dirent
**
namelist
,
int
n
,
int
current
=
0
)
int
current
=
0
)
:
basepath
(
basepath
),
namelist
(
namelist
),
n
(
n
),
current
(
current
)
{
:
basepath
(
basepath
),
namelist
(
namelist
),
n
(
n
),
current
(
current
)
{
if
(
this
->
basepath
[
this
->
basepath
.
size
()
-
1
]
!=
'/'
)
{
if
(
this
->
basepath
[
this
->
basepath
.
size
()
-
1
]
!=
'/'
)
{
...
@@ -80,9 +80,9 @@ struct os_t {
...
@@ -80,9 +80,9 @@ struct os_t {
}
}
}
}
type
()
{}
py_
type
()
{}
bool
operator
!=
(
const
type
&
other
)
{
bool
operator
!=
(
const
py_
type
&
other
)
{
return
this
->
current
!=
other
.
current
;
return
this
->
current
!=
other
.
current
;
}
}
...
@@ -103,7 +103,7 @@ struct os_t {
...
@@ -103,7 +103,7 @@ struct os_t {
STATX_SIZE
,
&
statxbuf
))
{
STATX_SIZE
,
&
statxbuf
))
{
system_error
(
-
err
,
"statx()"
);
system_error
(
-
err
,
"statx()"
);
}
}
co_return
PyObj
<
Stat_Result_s
>
(
new
Stat_Result_s
::
type
{
co_return
PyObj
<
Stat_Result_s
>
(
new
Stat_Result_s
::
py_
type
{
statxbuf
.
stx_mode
,
statxbuf
.
stx_mode
,
statxbuf
.
stx_ino
,
statxbuf
.
stx_ino
,
makedev
(
statxbuf
.
stx_dev_major
,
statxbuf
.
stx_dev_minor
),
makedev
(
statxbuf
.
stx_dev_major
,
statxbuf
.
stx_dev_minor
),
...
...
rt/include/python/socket.hpp
View file @
d57706f4
...
@@ -23,13 +23,13 @@ struct socket_t {
...
@@ -23,13 +23,13 @@ struct socket_t {
static
constexpr
int
AF_UNIX
=
1
;
static
constexpr
int
AF_UNIX
=
1
;
struct
socket_s
{
struct
socket_s
{
struct
type
{
struct
py_
type
{
METHOD
(
typon
::
Task
<
std
::
tuple
<
PyObj
<
type
>
COMMA
()
std
::
string
>>
,
accept
,
(
Self
self
),
{
METHOD
(
typon
::
Task
<
std
::
tuple
<
PyObj
<
py_
type
>
COMMA
()
std
::
string
>>
,
accept
,
(
Self
self
),
{
int
connfd
=
co_await
typon
::
io
::
accept
(
self
->
fd
,
NULL
,
NULL
);
int
connfd
=
co_await
typon
::
io
::
accept
(
self
->
fd
,
NULL
,
NULL
);
if
(
connfd
<
0
)
{
if
(
connfd
<
0
)
{
system_error
(
-
connfd
,
"accept()"
);
system_error
(
-
connfd
,
"accept()"
);
}
}
co_return
std
::
make_tuple
(
pyobj
<
type
>
(
connfd
),
std
::
string
(
""
));
// TODO
co_return
std
::
make_tuple
(
pyobj
<
py_
type
>
(
connfd
),
std
::
string
(
""
));
// TODO
})
})
METHOD
(
typon
::
Task
<
void
>
,
close
,
(
Self
self
),
METHOD
(
typon
::
Task
<
void
>
,
close
,
(
Self
self
),
...
@@ -74,9 +74,9 @@ struct socket_t {
...
@@ -74,9 +74,9 @@ struct socket_t {
}
}
})
})
type
(
int
fd
=
-
1
)
:
fd
(
fd
)
{}
py_
type
(
int
fd
=
-
1
)
:
fd
(
fd
)
{}
type
(
const
type
&
other
)
py_type
(
const
py_
type
&
other
)
:
fd
(
other
.
fd
)
{}
:
fd
(
other
.
fd
)
{}
int
fd
;
int
fd
;
...
@@ -84,7 +84,7 @@ struct socket_t {
...
@@ -84,7 +84,7 @@ struct socket_t {
auto
operator
()(
int
family
,
int
type_
)
{
auto
operator
()(
int
family
,
int
type_
)
{
if
(
int
fd
=
::
socket
(
family
,
type_
,
0
);
fd
>=
0
)
{
if
(
int
fd
=
::
socket
(
family
,
type_
,
0
);
fd
>=
0
)
{
return
pyobj
<
type
>
(
fd
);
return
pyobj
<
py_
type
>
(
fd
);
}
else
{
}
else
{
system_error
(
errno
,
"socket()"
);
system_error
(
errno
,
"socket()"
);
}
}
...
...
trans/stdlib/__init__.py
View file @
d57706f4
...
@@ -14,11 +14,14 @@ class int:
...
@@ -14,11 +14,14 @@ class int:
def
__and__
(
self
,
other
:
Self
)
->
Self
:
...
def
__and__
(
self
,
other
:
Self
)
->
Self
:
...
def
__neg__
(
self
)
->
Self
:
...
def
__neg__
(
self
)
->
Self
:
...
def
__init__
(
self
,
x
:
str
)
->
None
:
...
def
__init__
(
self
,
x
:
object
)
->
None
:
...
def
__lt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__lt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__gt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__gt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__mod__
(
self
,
other
:
Self
)
->
Self
:
...
def
__mod__
(
self
,
other
:
Self
)
->
Self
:
...
def
__ge__
(
self
,
other
:
Self
)
->
bool
:
...
class
float
:
def
__init__
(
self
,
x
:
object
)
->
None
:
...
assert
int
.
__add__
assert
int
.
__add__
U
=
TypeVar
(
"U"
)
U
=
TypeVar
(
"U"
)
...
@@ -51,6 +54,8 @@ class str:
...
@@ -51,6 +54,8 @@ class str:
def
__mul__
(
self
,
other
:
int
)
->
Self
:
...
def
__mul__
(
self
,
other
:
int
)
->
Self
:
...
def
startswith
(
self
,
prefix
:
Self
)
->
bool
:
...
def
startswith
(
self
,
prefix
:
Self
)
->
bool
:
...
def
__getitem__
(
self
,
item
:
int
|
slice
)
->
Self
:
...
def
__getitem__
(
self
,
item
:
int
|
slice
)
->
Self
:
...
def
isspace
(
self
)
->
bool
:
...
def
__contains__
(
self
,
item
:
Self
)
->
bool
:
...
assert
len
(
"a"
)
assert
len
(
"a"
)
...
@@ -120,6 +125,8 @@ def print(*args) -> None: ...
...
@@ -120,6 +125,8 @@ def print(*args) -> None: ...
assert
print
assert
print
def
input
(
prompt
:
str
=
""
)
->
str
:
...
def
range
(
*
args
)
->
Iterator
[
int
]:
...
def
range
(
*
args
)
->
Iterator
[
int
]:
...
...
@@ -158,4 +165,9 @@ class __test_type:
...
@@ -158,4 +165,9 @@ class __test_type:
assert
__test_type
().
test_opt
(
5
)
assert
__test_type
().
test_opt
(
5
)
assert
__test_type
().
test_opt
(
5
,
6
)
assert
__test_type
().
test_opt
(
5
,
6
)
assert
not
__test_type
().
test_opt
(
5
,
6
,
7
)
assert
not
__test_type
().
test_opt
(
5
,
6
,
7
)
assert
not
__test_type
().
test_opt
()
assert
not
__test_type
().
test_opt
()
\ No newline at end of file
def
exit
(
code
:
int
|
None
=
None
)
->
None
:
...
class
Exception
:
def
__init__
(
self
,
message
:
str
)
->
None
:
...
\ No newline at end of file
trans/stdlib/enum_.py
0 → 100644
View file @
d57706f4
# coding: utf-8
Enum
:
BuiltinFeature
[
"Enum"
]
\ No newline at end of file
trans/tests/a_a_a_a_a_a_errtest.py
View file @
d57706f4
import
sys
import
sys
import
math
import
math
from
typing
import
Callable
# def f(x: Callable[[int], int]):
# return x(5)
x
=
4
def
f
():
if
True
:
next
=
5
x
=
7
def
g
():
nonlocal
x
x
=
6
return
123
# def h(x):
# y = len(x)
# z = x[4]
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
a
=
[
n
for
n
in
range
(
10
)]
#print(f(lambda n: n + 1)) # todo
b
=
[
x
for
x
in
a
if
x
%
2
==
0
]
print
(
f
())
c
=
[
y
*
y
for
y
in
b
]
print
(
a
,
b
,
c
)
\ No newline at end of file
for
i
in
range
(
10
):
if
i
>
4
:
break
else
:
print
(
"else"
)
\ No newline at end of file
trans/tests/a_a_a_a_calcbasic.py
View file @
d57706f4
from
dataclasses
import
dataclass
from
dataclasses
import
dataclass
from
typing
import
Any
,
Callable
from
typing
import
Any
,
Callable
,
Optional
from
enum
import
Enum
from
enum
import
Enum
from
itertools
import
groupby
import
operator
import
operator
import
string
@
dataclass
@
dataclass
class
BinOperator
:
class
BinOperator
:
symbol
:
str
symbol
:
str
priority
:
int
priority
:
int
perform
:
Callable
[[
float
,
float
],
float
]
perform
:
Callable
[[
float
,
float
],
float
]
OPERATORS
=
[
OPERATORS
=
[
BinOperator
(
"+"
,
0
,
operator
.
add
),
BinOperator
(
"+"
,
0
,
operator
.
add
),
BinOperator
(
"-"
,
0
,
operator
.
sub
),
BinOperator
(
"-"
,
0
,
operator
.
sub
),
BinOperator
(
"*"
,
1
,
operator
.
mul
),
BinOperator
(
"*"
,
1
,
operator
.
mul
),
BinOperator
(
"/"
,
1
,
operator
.
truediv
)
BinOperator
(
"/"
,
1
,
operator
.
truediv
)
]
]
# ops_by_priority = [list(it) for _, it in groupby(OPERATORS, lambda op: op.priority)]
ops_by_priority
=
[
list
(
it
)
for
_
,
it
in
groupby
(
OPERATORS
,
lambda
op
:
op
.
priority
)]
ops_by_priority
=
[
[
OPERATORS
[
0
],
OPERATORS
[
1
]],
[
OPERATORS
[
2
],
OPERATORS
[
3
]]
]
MAX_PRIORITY
=
len
(
ops_by_priority
)
MAX_PRIORITY
=
len
(
ops_by_priority
)
ops_syms
=
[
op
.
symbol
for
op
in
OPERATORS
]
ops_syms
=
[
op
.
symbol
for
op
in
OPERATORS
]
class
TokenType
(
Enum
):
class
TokenType
(
Enum
):
NUMBER
=
1
NUMBER
=
1
PARENTHESIS
=
2
PARENTHESIS
=
2
OPERATION
=
3
OPERATION
=
3
@
dataclass
@
dataclass
class
Token
:
class
Token
:
type
:
TokenType
type
:
TokenType
val
:
Any
val
:
str
num
:
float
def
tokenize
(
inp
:
str
):
def
tokenize
(
inp
:
str
):
tokens
=
[]
tokens
=
[]
index
=
0
def
skip_spaces
():
nonlocal
index
while
inp
[
index
].
isspace
():
index
+=
1
def
has
():
return
index
<
len
(
inp
)
def
peek
():
return
inp
[
index
]
def
read
():
nonlocal
index
index
+=
1
return
inp
[
index
-
1
]
def
read_number
():
res
=
""
while
True
:
res
+=
read
()
if
not
has
()
or
peek
()
not
in
"0123456789."
:
break
index
=
0
return
Token
(
TokenType
.
NUMBER
,
res
,
float
(
res
))
# if "." in res else int(res))
def
skip_spaces
():
nonlocal
index
while
inp
[
index
].
isspace
():
index
+=
1
def
has
():
return
index
<
len
(
inp
)
def
peek
():
return
inp
[
index
]
def
read
():
while
has
():
nonlocal
index
skip_spaces
()
index
+=
1
return
inp
[
index
-
1
]
def
read_number
():
next
=
peek
()
res
=
""
while
True
:
tok
:
Token
res
+=
read
()
if
not
has
()
or
peek
()
not
in
"0123456789."
:
break
return
Token
(
TokenType
.
NUMBER
,
float
(
res
)
if
"."
in
res
else
int
(
res
))
if
next
in
ops_syms
:
tok
=
Token
(
TokenType
.
OPERATION
,
read
(),
0
)
elif
next
in
"()"
:
tok
=
Token
(
TokenType
.
PARENTHESIS
,
read
(),
0
)
elif
next
in
"0123456789."
:
tok
=
read_number
()
else
:
raise
Exception
(
"invalid character '{}' at {}"
.
format
(
next
,
index
))
while
has
():
tokens
.
append
(
tok
)
skip_spaces
()
next
=
peek
()
return
tokens
if
next
in
ops_syms
:
tok
=
Token
(
TokenType
.
OPERATION
,
read
())
elif
next
in
"()"
:
tok
=
Token
(
TokenType
.
PARENTHESIS
,
read
())
elif
next
in
"0123456789."
:
tok
=
read_number
()
else
:
raise
Exception
(
f"invalid character '
{
next
}
'"
,
index
)
tokens
.
append
(
tok
)
def
parse
(
tokens
:
list
[
Token
]):
index
=
0
return
tokens
def
has
():
return
index
<
len
(
tokens
)
def
current
():
if
not
has
():
raise
Exception
(
"expected token, got EOL"
)
return
tokens
[
index
]
def
parse
(
tokens
):
def
match
(
type
:
TokenType
,
val
:
Optional
[
str
]
=
None
):
index
=
0
return
has
()
and
tokens
[
index
].
type
==
type
and
(
val
is
None
or
tokens
[
index
].
val
==
val
)
def
has
():
def
accept
(
type
:
TokenType
,
val
:
Optional
[
str
]
=
None
):
return
index
<
len
(
tokens
)
nonlocal
index
if
match
(
type
,
val
):
index
+=
1
return
True
return
False
def
current
():
def
expect
(
type
:
TokenType
,
val
:
Optional
[
str
]
=
None
):
if
not
has
():
nonlocal
index
raise
Exception
(
"expected token, got EOL"
)
if
match
(
type
,
val
):
return
tokens
[
index
]
index
+=
1
return
tokens
[
index
-
1
]
if
not
has
():
raise
Exception
(
"expected {}, got EOL"
.
format
(
type
))
else
:
raise
Exception
(
"expected {}, got {}"
.
format
(
type
,
current
().
type
))
def
match
(
type
:
TokenType
,
val
:
Any
=
None
):
parse_term
:
Callable
[[],
None
]
return
has
()
and
tokens
[
index
].
type
==
type
and
(
val
is
None
or
tokens
[
index
].
val
==
val
)
def
accept
(
type
:
TokenType
,
val
:
Any
=
None
):
def
parse_bin
(
priority
=
0
):
nonlocal
index
if
priority
>=
MAX_PRIORITY
:
if
match
(
type
,
val
):
return
parse_term
()
index
+=
1
return
True
return
False
def
expect
(
type
:
TokenType
,
val
:
Any
=
None
):
left
=
parse_bin
(
priority
+
1
)
nonlocal
index
ops
=
ops_by_priority
[
priority
]
if
match
(
type
,
val
):
index
+=
1
return
tokens
[
index
-
1
]
if
not
has
():
raise
Exception
(
f"expected
{
type
}
, got EOL"
)
else
:
raise
Exception
(
f"expected
{
type
}
, got
{
current
().
type
}
"
)
def
parse_bin
(
priority
=
0
):
while
has
()
and
current
().
type
==
TokenType
.
OPERATION
:
if
priority
>=
MAX_PRIORITY
:
for
op
in
ops
:
return
parse_term
()
if
accept
(
TokenType
.
OPERATION
,
op
.
symbol
):
right
=
parse_bin
(
priority
+
1
)
left
=
parse_bin
(
priority
+
1
)
left
=
op
.
perform
(
left
,
right
)
ops
=
ops_by_priority
[
priority
]
break
else
:
break
while
has
()
and
current
().
type
==
TokenType
.
OPERATION
:
return
left
for
op
in
ops
:
if
accept
(
TokenType
.
OPERATION
,
op
.
symbol
):
right
=
parse_bin
(
priority
+
1
)
left
=
op
.
perform
(
left
,
right
)
break
else
:
break
return
left
def
parse_expr
():
return
parse_bin
()
def
parse_term
():
def
parse_term
():
token
=
current
()
token
=
current
()
if
token
.
type
==
TokenType
.
NUMBER
:
if
token
.
type
==
TokenType
.
NUMBER
:
return
expect
(
TokenType
.
NUMBER
).
val
return
expect
(
TokenType
.
NUMBER
).
num
elif
accept
(
TokenType
.
PARENTHESIS
,
"("
):
elif
accept
(
TokenType
.
PARENTHESIS
,
"("
):
val
=
parse_expr
()
val
=
parse_expr
()
expect
(
TokenType
.
PARENTHESIS
,
")"
)
expect
(
TokenType
.
PARENTHESIS
,
")"
)
return
val
return
val
else
:
else
:
raise
Exception
(
f"expected term, got
{
token
.
type
}
"
)
raise
Exception
(
"expected term, got {}"
.
format
(
token
.
type
)
)
def
parse_expr
():
return
parse_expr
()
return
parse_bin
()
return
parse_expr
()
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
while
True
:
while
True
:
inp
=
input
(
"> "
)
# inp = input("> ")
try
:
inp
=
"2 + 3 * 4"
tok
=
tokenize
(
inp
)
try
:
res
=
parse
(
tok
)
tok
=
tokenize
(
inp
)
print
(
res
)
res
=
parse
(
tok
)
except
Exception
as
e
:
print
(
res
)
print
(
e
)
except
Exception
as
e
:
print
()
# print(e)
pass
print
()
break
trans/tests/usertype.py
→
trans/tests/
a_a_a_a_
usertype.py
View file @
d57706f4
File moved
trans/tests/builtins_test.py
View file @
d57706f4
...
@@ -42,7 +42,10 @@ if __name__ == "__main__":
...
@@ -42,7 +42,10 @@ if __name__ == "__main__":
sum
=
0
sum
=
0
for
i
in
range
(
15
):
for
i
in
range
(
15
):
sum
+=
i
sum
+=
i
a
=
[
n
for
n
in
range
(
10
)]
b
=
[
x
for
x
in
a
if
x
%
2
==
0
]
c
=
[
y
*
y
for
y
in
b
]
print
(
"C++ "
if
is_cpp
()
else
"Python"
,
print
(
"C++ "
if
is_cpp
()
else
"Python"
,
"res="
,
5
,
"."
,
True
,
[
4
,
5
,
6
],
{
7
,
8
,
9
},
[
1
,
2
]
+
[
3
,
4
],
[
5
,
6
]
*
3
,
{
1
:
7
,
9
:
3
},
0x55
&
7
==
5
,
"res="
,
5
,
"."
,
True
,
[
4
,
5
,
6
],
{
7
,
8
,
9
},
[
1
,
2
]
+
[
3
,
4
],
[
5
,
6
]
*
3
,
{
1
:
7
,
9
:
3
},
0x55
&
7
==
5
,
3j
,
sum
)
3j
,
sum
,
a
,
b
,
c
)
print
()
print
()
trans/transpiler/phases/emit_cpp/__init__.py
View file @
d57706f4
...
@@ -9,7 +9,7 @@ from transpiler.phases.emit_cpp.consts import MAPPINGS
...
@@ -9,7 +9,7 @@ from transpiler.phases.emit_cpp.consts import MAPPINGS
from
transpiler.phases.typing
import
TypeVariable
from
transpiler.phases.typing
import
TypeVariable
from
transpiler.phases.typing.exceptions
import
UnresolvedTypeVariableError
from
transpiler.phases.typing.exceptions
import
UnresolvedTypeVariableError
from
transpiler.phases.typing.types
import
BaseType
,
TY_INT
,
TY_BOOL
,
TY_NONE
,
Promise
,
PromiseKind
,
TY_STR
,
UserType
,
\
from
transpiler.phases.typing.types
import
BaseType
,
TY_INT
,
TY_BOOL
,
TY_NONE
,
Promise
,
PromiseKind
,
TY_STR
,
UserType
,
\
TypeType
,
TypeOperator
,
TY_FLOAT
TypeType
,
TypeOperator
,
TY_FLOAT
,
FunctionType
from
transpiler.utils
import
UnsupportedNodeError
,
highlight
from
transpiler.utils
import
UnsupportedNodeError
,
highlight
...
@@ -70,6 +70,12 @@ class NodeVisitor(UniversalVisitor):
...
@@ -70,6 +70,12 @@ class NodeVisitor(UniversalVisitor):
yield
f"PyObj<decltype(
{
node
.
name
}
)>"
yield
f"PyObj<decltype(
{
node
.
name
}
)>"
elif
isinstance
(
node
,
TypeType
):
elif
isinstance
(
node
,
TypeType
):
yield
"auto"
# TODO
yield
"auto"
# TODO
elif
isinstance
(
node
,
FunctionType
):
yield
"std::function<"
yield
from
self
.
visit
(
node
.
return_type
)
yield
"("
yield
from
join
(
", "
,
map
(
self
.
visit
,
node
.
parameters
))
yield
")>"
elif
isinstance
(
node
,
Promise
):
elif
isinstance
(
node
,
Promise
):
yield
"typon::"
yield
"typon::"
if
node
.
kind
==
PromiseKind
.
TASK
:
if
node
.
kind
==
PromiseKind
.
TASK
:
...
@@ -88,7 +94,7 @@ class NodeVisitor(UniversalVisitor):
...
@@ -88,7 +94,7 @@ class NodeVisitor(UniversalVisitor):
yield
from
self
.
visit
(
node
.
return_type
)
yield
from
self
.
visit
(
node
.
return_type
)
yield
">"
yield
">"
elif
isinstance
(
node
,
TypeVariable
):
elif
isinstance
(
node
,
TypeVariable
):
#yield f"TYPEVAR_{node.name}";return
#
yield f"TYPEVAR_{node.name}";return
raise
UnresolvedTypeVariableError
(
node
)
raise
UnresolvedTypeVariableError
(
node
)
elif
isinstance
(
node
,
TypeOperator
):
elif
isinstance
(
node
,
TypeOperator
):
yield
"typon::Py"
+
node
.
name
.
title
()
yield
"typon::Py"
+
node
.
name
.
title
()
...
...
trans/transpiler/phases/emit_cpp/class_.py
View file @
d57706f4
...
@@ -13,17 +13,17 @@ class ClassVisitor(NodeVisitor):
...
@@ -13,17 +13,17 @@ class ClassVisitor(NodeVisitor):
yield
f"extern
{
node
.
name
}
_s
{
node
.
name
}
;"
yield
f"extern
{
node
.
name
}
_s
{
node
.
name
}
;"
yield
f"struct
{
node
.
name
}
_s {{"
yield
f"struct
{
node
.
name
}
_s {{"
yield
"struct type {"
yield
"struct
py_
type {"
inner
=
ClassInnerVisitor
(
node
.
inner_scope
)
inner
=
ClassInnerVisitor
(
node
.
inner_scope
)
for
stmt
in
node
.
body
:
for
stmt
in
node
.
body
:
yield
from
inner
.
visit
(
stmt
)
yield
from
inner
.
visit
(
stmt
)
yield
"template<typename... T> type(T&&... args) {"
yield
"template<typename... T>
py_
type(T&&... args) {"
yield
"__init__(this, std::forward<T>(args)...);"
yield
"__init__(this, std::forward<T>(args)...);"
yield
"}"
yield
"}"
yield
"type() {}"
yield
"
py_
type() {}"
yield
"
type(const
type&) = delete;"
yield
"
py_type(const py_
type&) = delete;"
yield
"
type(
type&&) = delete;"
yield
"
py_type(py_
type&&) = delete;"
yield
"void py_repr(std::ostream &s) const {"
yield
"void py_repr(std::ostream &s) const {"
yield
"s << '{';"
yield
"s << '{';"
...
@@ -42,7 +42,7 @@ class ClassVisitor(NodeVisitor):
...
@@ -42,7 +42,7 @@ class ClassVisitor(NodeVisitor):
yield
"};"
yield
"};"
yield
"template<typename... T> auto operator()(T&&... args) {"
yield
"template<typename... T> auto operator()(T&&... args) {"
yield
"return pyobj<type>(std::forward<T>(args)...);"
yield
"return pyobj<
py_
type>(std::forward<T>(args)...);"
yield
"}"
yield
"}"
# outer = ClassOuterVisitor(node.inner_scope)
# outer = ClassOuterVisitor(node.inner_scope)
...
@@ -61,6 +61,11 @@ class ClassInnerVisitor(NodeVisitor):
...
@@ -61,6 +61,11 @@ class ClassInnerVisitor(NodeVisitor):
yield
node
.
target
.
id
yield
node
.
target
.
id
yield
";"
yield
";"
def
visit_Assign
(
self
,
node
:
ast
.
Assign
)
->
Iterable
[
str
]:
yield
"static constexpr"
from
transpiler.phases.emit_cpp.block
import
BlockVisitor
yield
from
BlockVisitor
(
self
.
scope
).
visit_Assign
(
node
)
def
visit_FunctionDef
(
self
,
node
:
ast
.
FunctionDef
)
->
Iterable
[
str
]:
def
visit_FunctionDef
(
self
,
node
:
ast
.
FunctionDef
)
->
Iterable
[
str
]:
# yield "struct {"
# yield "struct {"
# yield "type* self;"
# yield "type* self;"
...
...
trans/transpiler/phases/emit_cpp/consts.py
View file @
d57706f4
...
@@ -74,6 +74,7 @@ PRECEDENCE_LEVELS = {op: i for i, ops in enumerate(PRECEDENCE) for op in ops}
...
@@ -74,6 +74,7 @@ PRECEDENCE_LEVELS = {op: i for i, ops in enumerate(PRECEDENCE) for op in ops}
MAPPINGS
=
{
MAPPINGS
=
{
"True"
:
"true"
,
"True"
:
"true"
,
"False"
:
"false"
,
"False"
:
"false"
,
"None"
:
"nullptr"
"None"
:
"nullptr"
,
"operator"
:
"operator_"
,
}
}
"""Mapping of Python builtin constants to C++ equivalents."""
"""Mapping of Python builtin constants to C++ equivalents."""
trans/transpiler/phases/emit_cpp/expr.py
View file @
d57706f4
...
@@ -3,7 +3,7 @@ import ast
...
@@ -3,7 +3,7 @@ import ast
from
dataclasses
import
dataclass
,
field
from
dataclasses
import
dataclass
,
field
from
typing
import
List
,
Iterable
from
typing
import
List
,
Iterable
from
transpiler.phases.typing.types
import
UserType
,
FunctionType
,
Promise
from
transpiler.phases.typing.types
import
UserType
,
FunctionType
,
Promise
,
TypeType
from
transpiler.phases.utils
import
make_lnd
from
transpiler.phases.utils
import
make_lnd
from
transpiler.utils
import
compare_ast
,
linenodata
from
transpiler.utils
import
compare_ast
,
linenodata
from
transpiler.phases.emit_cpp.consts
import
SYMBOLS
,
PRECEDENCE_LEVELS
,
DUNDER_SYMBOLS
from
transpiler.phases.emit_cpp.consts
import
SYMBOLS
,
PRECEDENCE_LEVELS
,
DUNDER_SYMBOLS
...
@@ -215,11 +215,16 @@ class ExpressionVisitor(NodeVisitor):
...
@@ -215,11 +215,16 @@ class ExpressionVisitor(NodeVisitor):
yield
")"
yield
")"
def
visit_Attribute
(
self
,
node
:
ast
.
Attribute
)
->
Iterable
[
str
]:
def
visit_Attribute
(
self
,
node
:
ast
.
Attribute
)
->
Iterable
[
str
]:
if
isinstance
(
node
.
type
,
FunctionType
)
and
not
isinstance
(
node
.
value
.
type
,
Promise
):
use_dot
=
None
if
type
(
node
.
value
.
type
)
==
TypeType
:
use_dot
=
"dots"
elif
isinstance
(
node
.
type
,
FunctionType
)
and
not
isinstance
(
node
.
value
.
type
,
Promise
):
if
node
.
value
.
type
.
resolve
().
is_reference
:
if
node
.
value
.
type
.
resolve
().
is_reference
:
yield
"dotp"
use_dot
=
"dotp"
else
:
else
:
yield
"dot"
use_dot
=
"dot"
if
use_dot
:
yield
use_dot
yield
"(("
yield
"(("
yield
from
self
.
visit
(
node
.
value
)
yield
from
self
.
visit
(
node
.
value
)
yield
"), "
yield
"), "
...
...
trans/transpiler/phases/emit_cpp/function.py
View file @
d57706f4
...
@@ -4,7 +4,7 @@ from dataclasses import dataclass
...
@@ -4,7 +4,7 @@ from dataclasses import dataclass
from
typing
import
Iterable
from
typing
import
Iterable
from
transpiler.phases.emit_cpp.consts
import
SYMBOLS
from
transpiler.phases.emit_cpp.consts
import
SYMBOLS
from
transpiler.phases.emit_cpp
import
CoroutineMode
from
transpiler.phases.emit_cpp
import
CoroutineMode
,
FunctionEmissionKind
from
transpiler.phases.emit_cpp.block
import
BlockVisitor
from
transpiler.phases.emit_cpp.block
import
BlockVisitor
from
transpiler.phases.typing.scope
import
Scope
from
transpiler.phases.typing.scope
import
Scope
from
transpiler.phases.utils
import
PlainBlock
from
transpiler.phases.utils
import
PlainBlock
...
...
trans/transpiler/phases/emit_cpp/module.py
View file @
d57706f4
...
@@ -12,6 +12,7 @@ from transpiler.phases.emit_cpp.class_ import ClassVisitor
...
@@ -12,6 +12,7 @@ from transpiler.phases.emit_cpp.class_ import ClassVisitor
from
transpiler.phases.emit_cpp.function
import
FunctionVisitor
from
transpiler.phases.emit_cpp.function
import
FunctionVisitor
from
transpiler.utils
import
compare_ast
,
highlight
from
transpiler.utils
import
compare_ast
,
highlight
IGNORED_IMPORTS
=
{
"typon"
,
"typing"
,
"__future__"
,
"dataclasses"
,
"enum"
}
# noinspection PyPep8Naming
# noinspection PyPep8Naming
@
dataclass
@
dataclass
...
@@ -20,7 +21,7 @@ class ModuleVisitor(BlockVisitor):
...
@@ -20,7 +21,7 @@ class ModuleVisitor(BlockVisitor):
def
visit_Import
(
self
,
node
:
ast
.
Import
)
->
Iterable
[
str
]:
def
visit_Import
(
self
,
node
:
ast
.
Import
)
->
Iterable
[
str
]:
TB
=
f"emitting C++ code for
{
highlight
(
node
)
}
"
TB
=
f"emitting C++ code for
{
highlight
(
node
)
}
"
for
alias
in
node
.
names
:
for
alias
in
node
.
names
:
concrete
=
alias
.
asname
or
alias
.
name
concrete
=
self
.
fix_name
(
alias
.
asname
or
alias
.
name
)
if
alias
.
module_obj
.
is_python
:
if
alias
.
module_obj
.
is_python
:
yield
f"namespace py_
{
concrete
}
{{"
yield
f"namespace py_
{
concrete
}
{{"
yield
f"struct
{
concrete
}
_t {{"
yield
f"struct
{
concrete
}
_t {{"
...
@@ -33,7 +34,7 @@ class ModuleVisitor(BlockVisitor):
...
@@ -33,7 +34,7 @@ class ModuleVisitor(BlockVisitor):
yield
f"auto& get_all() {{ return all; }}"
yield
f"auto& get_all() {{ return all; }}"
yield
"}"
yield
"}"
yield
f'auto&
{
concrete
}
= py_
{
concrete
}
::get_all();'
yield
f'auto&
{
concrete
}
= py_
{
concrete
}
::get_all();'
elif
alias
.
name
in
{
"typon"
,
"typing"
,
"__future__"
}
:
elif
alias
.
name
in
IGNORED_IMPORTS
:
yield
""
yield
""
else
:
else
:
yield
from
self
.
import_module
(
alias
.
name
)
yield
from
self
.
import_module
(
alias
.
name
)
...
@@ -70,7 +71,7 @@ class ModuleVisitor(BlockVisitor):
...
@@ -70,7 +71,7 @@ class ModuleVisitor(BlockVisitor):
yield
f"}}
{
alias
}
;"
yield
f"}}
{
alias
}
;"
def
visit_ImportFrom
(
self
,
node
:
ast
.
ImportFrom
)
->
Iterable
[
str
]:
def
visit_ImportFrom
(
self
,
node
:
ast
.
ImportFrom
)
->
Iterable
[
str
]:
if
node
.
module
in
{
"typon"
,
"typing"
,
"__future__"
}
:
if
node
.
module
in
IGNORED_IMPORTS
:
yield
""
yield
""
elif
node
.
module_obj
.
is_python
:
elif
node
.
module_obj
.
is_python
:
for
alias
in
node
.
names
:
for
alias
in
node
.
names
:
...
...
trans/transpiler/phases/typing/block.py
View file @
d57706f4
...
@@ -6,7 +6,7 @@ from dataclasses import dataclass
...
@@ -6,7 +6,7 @@ from dataclasses import dataclass
from
transpiler.exceptions
import
CompileError
from
transpiler.exceptions
import
CompileError
from
transpiler.utils
import
highlight
,
linenodata
from
transpiler.utils
import
highlight
,
linenodata
from
transpiler.phases.typing
import
make_mod_decl
from
transpiler.phases.typing
import
make_mod_decl
from
transpiler.phases.typing.common
import
ScoperVisitor
,
get_iter
,
get_next
from
transpiler.phases.typing.common
import
ScoperVisitor
,
get_iter
,
get_next
,
is_builtin
from
transpiler.phases.typing.expr
import
ScoperExprVisitor
,
DUNDER
from
transpiler.phases.typing.expr
import
ScoperExprVisitor
,
DUNDER
from
transpiler.phases.typing.class_
import
ScoperClassVisitor
from
transpiler.phases.typing.class_
import
ScoperClassVisitor
from
transpiler.phases.typing.scope
import
VarDecl
,
VarKind
,
ScopeKind
,
Scope
from
transpiler.phases.typing.scope
import
VarDecl
,
VarKind
,
ScopeKind
,
Scope
...
@@ -19,9 +19,6 @@ from transpiler.phases.utils import PlainBlock, AnnotationName
...
@@ -19,9 +19,6 @@ from transpiler.phases.utils import PlainBlock, AnnotationName
class
ScoperBlockVisitor
(
ScoperVisitor
):
class
ScoperBlockVisitor
(
ScoperVisitor
):
stdlib
:
bool
=
False
stdlib
:
bool
=
False
def
expr
(
self
)
->
ScoperExprVisitor
:
return
ScoperExprVisitor
(
self
.
scope
,
self
.
root_decls
)
def
visit_Pass
(
self
,
node
:
ast
.
Pass
):
def
visit_Pass
(
self
,
node
:
ast
.
Pass
):
pass
pass
...
@@ -107,7 +104,7 @@ class ScoperBlockVisitor(ScoperVisitor):
...
@@ -107,7 +104,7 @@ class ScoperBlockVisitor(ScoperVisitor):
if
target
.
id
==
"_"
:
if
target
.
id
==
"_"
:
return
False
return
False
target
.
type
=
decl_val
target
.
type
=
decl_val
if
vdecl
:
=
self
.
scope
.
get
(
target
.
id
):
if
vdecl
:
=
self
.
scope
.
get
(
target
.
id
,
{
VarKind
.
LOCAL
,
VarKind
.
GLOBAL
,
VarKind
.
NONLOCAL
},
restrict_function
=
True
):
TB
=
f"unifying existing variable
{
highlight
(
target
.
id
)
}
of type
{
highlight
(
vdecl
.
type
)
}
with assigned value
{
highlight
(
decl_val
)
}
"
TB
=
f"unifying existing variable
{
highlight
(
target
.
id
)
}
of type
{
highlight
(
vdecl
.
type
)
}
with assigned value
{
highlight
(
decl_val
)
}
"
vdecl
.
type
.
unify
(
decl_val
)
vdecl
.
type
.
unify
(
decl_val
)
return
False
return
False
...
@@ -115,6 +112,7 @@ class ScoperBlockVisitor(ScoperVisitor):
...
@@ -115,6 +112,7 @@ class ScoperBlockVisitor(ScoperVisitor):
self
.
scope
.
vars
[
target
.
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
decl_val
)
self
.
scope
.
vars
[
target
.
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
decl_val
)
if
self
.
scope
.
kind
==
ScopeKind
.
FUNCTION_INNER
:
if
self
.
scope
.
kind
==
ScopeKind
.
FUNCTION_INNER
:
self
.
root_decls
[
target
.
id
]
=
VarDecl
(
VarKind
.
OUTER_DECL
,
decl_val
)
self
.
root_decls
[
target
.
id
]
=
VarDecl
(
VarKind
.
OUTER_DECL
,
decl_val
)
return
False
return
True
return
True
elif
isinstance
(
target
,
ast
.
Tuple
):
elif
isinstance
(
target
,
ast
.
Tuple
):
if
not
isinstance
(
decl_val
,
TupleType
):
if
not
isinstance
(
decl_val
,
TupleType
):
...
@@ -180,7 +178,7 @@ class ScoperBlockVisitor(ScoperVisitor):
...
@@ -180,7 +178,7 @@ class ScoperBlockVisitor(ScoperVisitor):
visitor
.
visit_block
(
node
.
body
)
visitor
.
visit_block
(
node
.
body
)
for
deco
in
node
.
decorator_list
:
for
deco
in
node
.
decorator_list
:
deco
=
self
.
expr
().
visit
(
deco
)
deco
=
self
.
expr
().
visit
(
deco
)
if
is
instance
(
deco
,
BuiltinFeature
)
and
deco
.
val
==
"dataclass"
:
if
is
_builtin
(
deco
,
"dataclass"
)
:
# init_type = FunctionType([cttype, *cttype.members.values()], TypeVariable())
# init_type = FunctionType([cttype, *cttype.members.values()], TypeVariable())
# cttype.methods["__init__"] = init_type
# cttype.methods["__init__"] = init_type
lnd
=
linenodata
(
node
)
lnd
=
linenodata
(
node
)
...
@@ -210,6 +208,13 @@ class ScoperBlockVisitor(ScoperVisitor):
...
@@ -210,6 +208,13 @@ class ScoperBlockVisitor(ScoperVisitor):
visitor
.
visit_function_definition
(
init_method
,
rtype
)
visitor
.
visit_function_definition
(
init_method
,
rtype
)
else
:
else
:
raise
NotImplementedError
(
deco
)
raise
NotImplementedError
(
deco
)
for
base
in
node
.
bases
:
base
=
self
.
expr
().
visit
(
base
)
if
is_builtin
(
base
,
"Enum"
):
for
k
in
ctype
.
members
:
ctype
.
members
[
k
]
=
ctype
else
:
raise
NotImplementedError
(
base
)
def
visit_If
(
self
,
node
:
ast
.
If
):
def
visit_If
(
self
,
node
:
ast
.
If
):
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
...
@@ -270,8 +275,8 @@ class ScoperBlockVisitor(ScoperVisitor):
...
@@ -270,8 +275,8 @@ class ScoperBlockVisitor(ScoperVisitor):
def
visit_Return
(
self
,
node
:
ast
.
Return
):
def
visit_Return
(
self
,
node
:
ast
.
Return
):
fct
=
self
.
scope
.
function
fct
=
self
.
scope
.
function
if
fct
is
None
:
if
fct
is
None
:
from
transpiler.phases.typing.exceptions
import
Return
OutsideFunctionError
from
transpiler.phases.typing.exceptions
import
OutsideFunctionError
raise
Return
OutsideFunctionError
()
raise
OutsideFunctionError
()
ftype
=
fct
.
obj_type
ftype
=
fct
.
obj_type
assert
isinstance
(
ftype
,
FunctionType
)
assert
isinstance
(
ftype
,
FunctionType
)
vtype
=
self
.
expr
().
visit
(
node
.
value
)
if
node
.
value
else
TY_NONE
vtype
=
self
.
expr
().
visit
(
node
.
value
)
if
node
.
value
else
TY_NONE
...
@@ -284,6 +289,16 @@ class ScoperBlockVisitor(ScoperVisitor):
...
@@ -284,6 +289,16 @@ class ScoperBlockVisitor(ScoperVisitor):
if
name
not
in
self
.
scope
.
global_scope
.
vars
:
if
name
not
in
self
.
scope
.
global_scope
.
vars
:
self
.
scope
.
global_scope
.
vars
[
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
None
)
self
.
scope
.
global_scope
.
vars
[
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
None
)
def
visit_Nonlocal
(
self
,
node
:
ast
.
Global
):
fct
=
self
.
scope
.
function
if
fct
is
None
:
from
transpiler.phases.typing.exceptions
import
OutsideFunctionError
raise
OutsideFunctionError
()
for
name
in
node
.
names
:
fct
.
vars
[
name
]
=
VarDecl
(
VarKind
.
NONLOCAL
,
None
)
if
name
not
in
fct
.
parent
.
vars
:
fct
.
parent
.
vars
[
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
None
)
def
visit_AugAssign
(
self
,
node
:
ast
.
AugAssign
):
def
visit_AugAssign
(
self
,
node
:
ast
.
AugAssign
):
target
,
value
=
map
(
self
.
get_type
,
(
node
.
target
,
node
.
value
))
target
,
value
=
map
(
self
.
get_type
,
(
node
.
target
,
node
.
value
))
try
:
try
:
...
...
trans/transpiler/phases/typing/class_.py
View file @
d57706f4
...
@@ -17,6 +17,14 @@ class ScoperClassVisitor(ScoperVisitor):
...
@@ -17,6 +17,14 @@ class ScoperClassVisitor(ScoperVisitor):
assert
isinstance
(
node
.
target
,
ast
.
Name
)
assert
isinstance
(
node
.
target
,
ast
.
Name
)
self
.
scope
.
obj_type
.
members
[
node
.
target
.
id
]
=
self
.
visit_annotation
(
node
.
annotation
)
self
.
scope
.
obj_type
.
members
[
node
.
target
.
id
]
=
self
.
visit_annotation
(
node
.
annotation
)
def
visit_Assign
(
self
,
node
:
ast
.
Assign
):
assert
len
(
node
.
targets
)
==
1
,
"Class field should be assigned to only once"
assert
isinstance
(
node
.
targets
[
0
],
ast
.
Name
)
node
.
is_declare
=
True
valtype
=
self
.
expr
().
visit
(
node
.
value
)
node
.
targets
[
0
].
type
=
valtype
self
.
scope
.
obj_type
.
members
[
node
.
targets
[
0
].
id
]
=
valtype
def
visit_FunctionDef
(
self
,
node
:
ast
.
FunctionDef
):
def
visit_FunctionDef
(
self
,
node
:
ast
.
FunctionDef
):
from
transpiler.phases.typing.block
import
ScoperBlockVisitor
from
transpiler.phases.typing.block
import
ScoperBlockVisitor
# TODO: maybe merge this code with ScoperBlockVisitor.visit_FunctionDef
# TODO: maybe merge this code with ScoperBlockVisitor.visit_FunctionDef
...
...
trans/transpiler/phases/typing/exceptions.py
View file @
d57706f4
...
@@ -271,9 +271,9 @@ class NotIteratorError(CompileError):
...
@@ -271,9 +271,9 @@ class NotIteratorError(CompileError):
"""
"""
@
dataclass
@
dataclass
class
Return
OutsideFunctionError
(
CompileError
):
class
OutsideFunctionError
(
CompileError
):
def
__str__
(
self
)
->
str
:
def
__str__
(
self
)
->
str
:
return
f"
{
highlight
(
'return'
)
}
cannot be used outside of a function"
return
f"
{
highlight
(
'return'
)
}
and
{
highlight
(
'nonlocal'
)
}
cannot be used outside of a function"
def
detail
(
self
,
last_node
:
ast
.
AST
=
None
)
->
str
:
def
detail
(
self
,
last_node
:
ast
.
AST
=
None
)
->
str
:
return
""
return
""
...
...
trans/transpiler/phases/typing/expr.py
View file @
d57706f4
...
@@ -105,6 +105,11 @@ class ScoperExprVisitor(ScoperVisitor):
...
@@ -105,6 +105,11 @@ class ScoperExprVisitor(ScoperVisitor):
ftype
=
self
.
visit
(
node
.
func
)
ftype
=
self
.
visit
(
node
.
func
)
if
ftype
.
typevars
:
if
ftype
.
typevars
:
ftype
=
ftype
.
gen_sub
(
None
,
{
v
.
name
:
TypeVariable
(
v
.
name
)
for
v
in
ftype
.
typevars
})
ftype
=
ftype
.
gen_sub
(
None
,
{
v
.
name
:
TypeVariable
(
v
.
name
)
for
v
in
ftype
.
typevars
})
from
transpiler.exceptions
import
CompileError
try
:
argtypes
=
[
self
.
visit
(
arg
)
for
arg
in
node
.
args
]
except
CompileError
as
e
:
pass
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
...
@@ -193,14 +198,20 @@ class ScoperExprVisitor(ScoperVisitor):
...
@@ -193,14 +198,20 @@ class ScoperExprVisitor(ScoperVisitor):
return
self
.
visit_getattr
(
p
,
name
)
return
self
.
visit_getattr
(
p
,
name
)
except
MissingAttributeError
as
e
:
except
MissingAttributeError
as
e
:
pass
pass
# class MemberProtocol(TypeOperator):
# pass
raise
MissingAttributeError
(
ltype
,
name
)
raise
MissingAttributeError
(
ltype
,
name
)
def
visit_List
(
self
,
node
:
ast
.
List
)
->
BaseType
:
def
visit_List
(
self
,
node
:
ast
.
List
)
->
BaseType
:
if
not
node
.
elts
:
if
not
node
.
elts
:
return
PyList
(
TypeVariable
())
return
PyList
(
TypeVariable
())
elems
=
[
self
.
visit
(
e
)
for
e
in
node
.
elts
]
elems
=
[
self
.
visit
(
e
)
for
e
in
node
.
elts
]
if
len
(
set
(
elems
))
!=
1
:
first
,
*
rest
=
elems
raise
NotImplementedError
(
"List with different types not handled yet"
)
for
e
in
rest
:
try
:
first
.
unify
(
e
)
except
:
raise
NotImplementedError
(
f"List with different types not handled yet:
{
', '
.
join
(
map
(
str
,
elems
))
}
"
)
return
PyList
(
elems
[
0
])
return
PyList
(
elems
[
0
])
def
visit_Set
(
self
,
node
:
ast
.
Set
)
->
BaseType
:
def
visit_Set
(
self
,
node
:
ast
.
Set
)
->
BaseType
:
...
...
trans/transpiler/phases/typing/scope.py
View file @
d57706f4
...
@@ -73,6 +73,8 @@ class Scope:
...
@@ -73,6 +73,8 @@ class Scope:
def
child
(
self
,
kind
:
ScopeKind
):
def
child
(
self
,
kind
:
ScopeKind
):
res
=
Scope
(
self
,
kind
,
self
.
function
,
self
.
global_scope
)
res
=
Scope
(
self
,
kind
,
self
.
function
,
self
.
global_scope
)
if
kind
==
ScopeKind
.
GLOBAL
:
res
.
global_scope
=
res
self
.
children
.
append
(
res
)
self
.
children
.
append
(
res
)
return
res
return
res
...
@@ -80,12 +82,18 @@ class Scope:
...
@@ -80,12 +82,18 @@ class Scope:
"""Declares a local variable"""
"""Declares a local variable"""
self
.
vars
[
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
type
)
self
.
vars
[
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
type
)
def
get
(
self
,
name
:
str
,
kind
:
VarKind
=
VarKind
.
LOCAL
)
->
Optional
[
VarDecl
]:
def
get
(
self
,
name
:
str
,
kind
:
VarKind
|
set
[
VarKind
]
=
VarKind
.
LOCAL
,
restrict_function
:
bool
=
False
)
->
Optional
[
VarDecl
]:
"""
"""
Gets the variable declaration of a variable in the current scope or any parent scope.
Gets the variable declaration of a variable in the current scope or any parent scope.
"""
"""
if
(
res
:
=
self
.
vars
.
get
(
name
))
and
res
.
kind
==
kind
:
if
type
(
kind
)
is
VarKind
:
kind
=
{
kind
}
if
(
res
:
=
self
.
vars
.
get
(
name
))
and
res
.
kind
in
kind
:
if
res
.
kind
==
VarKind
.
GLOBAL
:
return
self
.
global_scope
.
get
(
name
,
kind
)
elif
res
.
kind
==
VarKind
.
NONLOCAL
:
return
self
.
function
.
parent
.
get
(
name
,
VarKind
.
LOCAL
,
True
)
return
res
return
res
if
self
.
parent
is
not
None
:
if
self
.
parent
is
not
None
and
not
(
self
.
kind
==
ScopeKind
.
FUNCTION
and
restrict_function
)
:
return
self
.
parent
.
get
(
name
,
kind
)
return
self
.
parent
.
get
(
name
,
kind
,
restrict_function
)
return
None
return
None
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