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
fe2492d6
Commit
fe2492d6
authored
Mar 29, 2024
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
webserver_eval works, many things work
parent
909e37a5
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
338 additions
and
77 deletions
+338
-77
typon/include/python/builtins.hpp
typon/include/python/builtins.hpp
+10
-2
typon/include/python/builtins/dict.hpp
typon/include/python/builtins/dict.hpp
+11
-8
typon/include/python/builtins/slice.hpp
typon/include/python/builtins/slice.hpp
+31
-27
typon/include/python/builtins/str.hpp
typon/include/python/builtins/str.hpp
+57
-3
typon/runtime
typon/runtime
+1
-1
typon/trans/stdlib/builtins_.py
typon/trans/stdlib/builtins_.py
+2
-1
typon/trans/tests/webserver_eval.py
typon/trans/tests/webserver_eval.py
+7
-5
typon/trans/transpiler/phases/emit_cpp/expr.py
typon/trans/transpiler/phases/emit_cpp/expr.py
+8
-7
typon/trans/transpiler/phases/emit_cpp/function.py
typon/trans/transpiler/phases/emit_cpp/function.py
+8
-3
typon/trans/transpiler/phases/emit_cpp/module.py
typon/trans/transpiler/phases/emit_cpp/module.py
+37
-11
typon/trans/transpiler/phases/emit_cpp/visitors.py
typon/trans/transpiler/phases/emit_cpp/visitors.py
+2
-0
typon/trans/transpiler/phases/typing/block.py
typon/trans/transpiler/phases/typing/block.py
+4
-2
typon/trans/transpiler/phases/typing/expr.py
typon/trans/transpiler/phases/typing/expr.py
+8
-5
typon/trans/transpiler/phases/typing/modules.py
typon/trans/transpiler/phases/typing/modules.py
+3
-1
typon/trans/transpiler/phases/typing/scope.py
typon/trans/transpiler/phases/typing/scope.py
+1
-0
typon/trans/transpiler/phases/typing/stdlib.py
typon/trans/transpiler/phases/typing/stdlib.py
+5
-1
typon/trans/transpiler/phases/typing/types.py
typon/trans/transpiler/phases/typing/types.py
+1
-0
typon/trans/we2.cpp
typon/trans/we2.cpp
+142
-0
No files found.
typon/include/python/builtins.hpp
View file @
fe2492d6
...
@@ -65,8 +65,16 @@ namespace typon {
...
@@ -65,8 +65,16 @@ namespace typon {
// class TyNone {};
// class TyNone {};
using
TyNone
=
std
::
nullopt_t
;
//using TyNone = std::nullopt_t;
auto
None
=
std
::
nullopt
;
struct
TyNone
{
operator
bool
()
const
{
return
false
;
}
operator
std
::
nullopt_t
()
const
{
return
std
::
nullopt
;
}
template
<
typename
T
>
operator
std
::
optional
<
T
>
()
const
{
return
std
::
nullopt
;
}
};
auto
None
=
TyNone
{};
}
// namespace typon
}
// namespace typon
...
...
typon/include/python/builtins/dict.hpp
View file @
fe2492d6
...
@@ -173,21 +173,24 @@ struct TyDict__oo : classtype<_Base0, TyDict__oo<>> {
...
@@ -173,21 +173,24 @@ struct TyDict__oo : classtype<_Base0, TyDict__oo<>> {
template
<
typename
K
,
typename
V
>
template
<
typename
K
,
typename
V
>
struct
Obj
:
instance
<
TyDict__oo
<>
,
Obj
<
K
,
V
>>
{
struct
Obj
:
instance
<
TyDict__oo
<>
,
Obj
<
K
,
V
>>
{
using
map_type
=
std
::
unordered_map
<
K
,
V
>
;
std
::
shared_ptr
<
map_type
>
_m
;
std
::
shared_ptr
<
std
::
unordered_map
<
K
,
V
>>
_m
;
/*Obj(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {}
Obj
(
std
::
shared_ptr
<
std
::
unordered_map
<
K
,
V
>>
&&
m
)
:
_m
(
std
::
move
(
m
))
{}
Obj(std::unordered_map<K, V> &&m)
Obj(std::unordered_map<K, V> &&m)
: _m(std::move(
: _m(std::move(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>>
(
std
::
move
(
m
))))
{}
std::make_shared<std::unordered_map<K, V>>(std::move(m)))) {}
*/
Obj
(
std
::
initializer_list
<
std
::
pair
<
K
,
V
>
>
&&
m
)
Obj
(
std
::
initializer_list
<
typename
map_type
::
value_type
>
&&
m
)
:
_m
(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>
>
(
std
::
move
(
m
)))
{}
:
_m
(
std
::
make_shared
<
map_type
>
(
std
::
move
(
m
)))
{}
Obj
()
:
_m
(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>
>
())
{}
Obj
()
:
_m
(
std
::
make_shared
<
map_type
>
())
{}
template
<
typename
...
Args
>
template
<
typename
...
Args
>
Obj
(
Args
&&
...
args
)
Obj
(
Args
&&
...
args
)
:
_m
(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>
>
(
:
_m
(
std
::
make_shared
<
map_type
>
(
std
::
forward
<
Args
>
(
args
)...))
{}
std
::
forward
<
Args
>
(
args
)...))
{}
auto
begin
()
const
{
return
_m
->
begin
();
}
auto
end
()
const
{
return
_m
->
end
();
}
};
};
template
<
typename
T
>
auto
operator
()(
std
::
initializer_list
<
T
>
&&
v
)
const
{
template
<
typename
T
>
auto
operator
()(
std
::
initializer_list
<
T
>
&&
v
)
const
{
...
...
typon/include/python/builtins/slice.hpp
View file @
fe2492d6
...
@@ -13,6 +13,10 @@
...
@@ -13,6 +13,10 @@
namespace
typon
{
namespace
typon
{
using
namespace
referencemodel
;
using
namespace
referencemodel
;
struct
UnpackedSlice
{
ssize_t
start
,
stop
,
step
;
};
template
<
typename
_Base0
=
object
>
template
<
typename
_Base0
=
object
>
struct
TySlice__oo
:
classtype
<
_Base0
,
TySlice__oo
<>>
{
struct
TySlice__oo
:
classtype
<
_Base0
,
TySlice__oo
<>>
{
static
constexpr
std
::
string_view
name
=
"TySlice"
;
static
constexpr
std
::
string_view
name
=
"TySlice"
;
...
@@ -25,6 +29,33 @@ struct TySlice__oo : classtype<_Base0, TySlice__oo<>> {
...
@@ -25,6 +29,33 @@ struct TySlice__oo : classtype<_Base0, TySlice__oo<>> {
Obj
(
Start
start
,
Stop
stop
,
Step
step
)
Obj
(
Start
start
,
Stop
stop
,
Step
step
)
:
start
(
start
),
stop
(
stop
),
step
(
step
)
{}
:
start
(
start
),
stop
(
stop
),
step
(
step
)
{}
std
::
pair
<
ssize_t
,
UnpackedSlice
>
adjust_indices
(
ssize_t
seq_length
)
{
UnpackedSlice
res
;
if
constexpr
(
std
::
is_same_v
<
Step
,
TyNone
>
)
{
res
.
step
=
1
;
}
else
{
res
.
step
=
this
->
step
;
}
if
constexpr
(
std
::
is_same_v
<
Start
,
TyNone
>
)
{
res
.
start
=
res
.
step
<
0
?
PY_SSIZE_T_MAX
:
0
;
}
else
{
res
.
start
=
this
->
start
;
}
if
constexpr
(
std
::
is_same_v
<
Stop
,
TyNone
>
)
{
res
.
stop
=
res
.
step
<
0
?
PY_SSIZE_T_MIN
:
PY_SSIZE_T_MAX
;
}
else
{
res
.
stop
=
this
->
stop
;
}
auto
len
=
PySlice_AdjustIndices
(
seq_length
,
&
res
.
start
,
&
res
.
stop
,
res
.
step
);
return
{
len
,
res
};
}
};
};
template
<
typename
Stop
>
auto
operator
()(
Stop
stop
)
const
{
template
<
typename
Stop
>
auto
operator
()(
Stop
stop
)
const
{
...
@@ -64,36 +95,9 @@ static constexpr TySlice__oo<> TySlice{};
...
@@ -64,36 +95,9 @@ static constexpr TySlice__oo<> TySlice{};
std::optional<ssize_t> stop = 0;
std::optional<ssize_t> stop = 0;
std::optional<ssize_t> step = 1;
std::optional<ssize_t> step = 1;
struct UnpackedSlice {
ssize_t start, stop, step;
};
std::pair<ssize_t, UnpackedSlice> adjust_indices(ssize_t seq_length) {
UnpackedSlice res;
if (this->step == std::nullopt) {
res.step = 1;
} else {
res.step = this->step.value();
}
if (this->start == std::nullopt) {
res.start = res.step < 0 ? PY_SSIZE_T_MAX : 0;
} else {
res.start = this->start.value();
}
if (this->stop == std::nullopt) {
res.stop = res.step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX;
} else {
res.stop = this->stop.value();
}
auto len =
PySlice_AdjustIndices(seq_length, &res.start, &res.stop, res.step);
return {len, res};
}
};*/
};*/
#endif // TYPON_SLICE_HPP
#endif // TYPON_SLICE_HPP
typon/include/python/builtins/str.hpp
View file @
fe2492d6
...
@@ -178,6 +178,28 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
...
@@ -178,6 +178,28 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
// getitem
// getitem
struct
:
method
{
struct
:
method
{
auto
operator
()(
auto
self
,
TySlice__oo
<>::
Obj
<
auto
,
auto
,
auto
>
slice
)
const
{
auto
[
len
,
new_slice
]
=
slice
.
adjust_indices
(
self
->
value
.
size
());
Obj
result
;
result
.
value
.
reserve
(
len
);
if
(
new_slice
.
start
<
new_slice
.
stop
)
{
if
(
new_slice
.
step
>
0
)
{
for
(
auto
i
=
new_slice
.
start
;
i
<
new_slice
.
stop
;
i
+=
new_slice
.
step
)
{
result
.
value
.
push_back
(
self
->
value
[
i
]);
}
}
}
else
{
if
(
new_slice
.
step
<
0
)
{
for
(
auto
i
=
new_slice
.
start
;
i
>
new_slice
.
stop
;
i
+=
new_slice
.
step
)
{
result
.
value
.
push_back
(
self
->
value
[
i
]);
}
}
}
return
result
;
}
auto
operator
()(
auto
self
,
auto
index
)
const
{
auto
operator
()(
auto
self
,
auto
index
)
const
{
if
(
index
<
0
)
{
if
(
index
<
0
)
{
index
+=
self
->
value
.
size
();
index
+=
self
->
value
.
size
();
...
@@ -186,12 +208,24 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
...
@@ -186,12 +208,24 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
}
}
}
static
constexpr
oo__getitem__oo
{};
}
static
constexpr
oo__getitem__oo
{};
/*
struct : method {
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
auto
pos
=
self
->
value
.
find
(
other
->
value
);
auto
pos
=
self
->
value
.
find
(
other
->
value
);
return
typon::TyInt
(pos == std::string::npos ? -1 : pos);
return
(
pos
==
std
::
string
::
npos
?
-
1
:
pos
);
}
}
} static constexpr oo__find__oo{};*/
}
static
constexpr
find
{};
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
self
->
value
.
starts_with
(
other
->
value
);
}
}
static
constexpr
startswith
{};
struct
:
method
{
auto
operator
()(
auto
self
,
auto
encoding
=
Obj
(
std
::
string
(
"utf-8"
)))
const
{
return
Obj
(
self
->
value
);
}
}
static
constexpr
encode
{};
// format
// format
/*
/*
...
@@ -208,12 +242,19 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
...
@@ -208,12 +242,19 @@ struct TyStr__oo : classtype<_Base0, TyStr__oo<>> {
}
static
constexpr
format
{};
}
static
constexpr
format
{};
struct
Obj
:
value
<
TyStr__oo
<>
,
Obj
>
{
struct
Obj
:
value
<
TyStr__oo
<>
,
Obj
>
{
using
value_type
=
std
::
string
::
value_type
;
std
::
string
value
;
std
::
string
value
;
constexpr
Obj
()
:
value
()
{}
constexpr
Obj
()
:
value
()
{}
constexpr
Obj
(
std
::
string
value
)
:
value
(
value
)
{}
constexpr
Obj
(
std
::
string
value
)
:
value
(
value
)
{}
constexpr
Obj
(
const
char
*
value
,
size_t
count
)
:
value
(
value
,
count
)
{}
operator
std
::
string
()
const
{
return
value
;
}
operator
std
::
string
()
const
{
return
value
;
}
operator
std
::
string_view
()
const
{
return
value
;
}
operator
std
::
string_view
()
const
{
return
value
;
}
auto
data
()
const
{
return
value
.
data
();
}
auto
size
()
const
{
return
value
.
size
();
}
bool
operator
==
(
const
Obj
&
other
)
const
{
return
value
==
other
.
value
;
}
};
};
auto
operator
()(
std
::
string
value
)
const
{
return
Obj
(
value
);
}
auto
operator
()(
std
::
string
value
)
const
{
return
Obj
(
value
);
}
...
@@ -226,6 +267,12 @@ inline constexpr auto operator""_ps(const char *s, size_t len) noexcept {
...
@@ -226,6 +267,12 @@ inline constexpr auto operator""_ps(const char *s, size_t len) noexcept {
return
typon
::
TyStr__oo
<>::
Obj
(
std
::
string
(
s
,
len
));
return
typon
::
TyStr__oo
<>::
Obj
(
std
::
string
(
s
,
len
));
}
}
template
<
>
struct
std
::
hash
<
decltype
(
""
_ps
)
>
{
std
::
size_t
operator
()(
const
decltype
(
""
_ps
)
&
s
)
const
noexcept
{
return
std
::
hash
<
std
::
string
>
()(
s
);
}
};
/*template <typename T> auto str(const T &x) { return dot(x, oo__str__oo)(); }
/*template <typename T> auto str(const T &x) { return dot(x, oo__str__oo)(); }
template <typename T>
template <typename T>
...
@@ -264,4 +311,11 @@ template <typename T> auto repr(const T &x) {
...
@@ -264,4 +311,11 @@ template <typename T> auto repr(const T &x) {
}
}
}
}
namespace
PYBIND11_NAMESPACE
{
namespace
detail
{
template
<
>
struct
type_caster
<
decltype
(
""
_ps
)
>
:
string_caster
<
decltype
(
""
_ps
)
>
{};
}}
#endif // TYPON_STR_HPP
#endif // TYPON_STR_HPP
runtime
@
f58767e0
Subproject commit
76287636438cf0a82701102ccb8014c66ea88506
Subproject commit
f58767e045d32aaaed44c68082220e08c481c159
typon/trans/stdlib/builtins_.py
View file @
fe2492d6
...
@@ -49,7 +49,8 @@ class Iterable[U](Protocol):
...
@@ -49,7 +49,8 @@ class Iterable[U](Protocol):
class
str
:
class
str
:
def
find
(
self
,
sub
:
Self
)
->
int
:
...
def
find
(
self
,
sub
:
Self
)
->
int
:
...
def
format
(
self
,
*
args
)
->
Self
:
...
def
format
(
self
,
*
args
)
->
Self
:
...
def
encode
(
self
,
encoding
:
Self
)
->
bytes
:
...
def
encode
(
self
,
encoding
:
Self
)
->
Self
:
...
# TODO: bytes
def
decode
(
self
,
encoding
:
Self
)
->
Self
:
...
def
__len__
(
self
)
->
int
:
...
def
__len__
(
self
)
->
int
:
...
def
__add__
(
self
,
other
:
Self
)
->
Self
:
...
def
__add__
(
self
,
other
:
Self
)
->
Self
:
...
def
__mul__
(
self
,
other
:
int
)
->
Self
:
...
def
__mul__
(
self
,
other
:
int
)
->
Self
:
...
...
...
typon/trans/tests/webserver_eval.py
View file @
fe2492d6
...
@@ -3,8 +3,7 @@
...
@@ -3,8 +3,7 @@
import
sys
import
sys
from
socket
import
socket
,
SOCK_STREAM
,
AF_INET6
,
SOL_SOCKET
,
SO_REUSEADDR
from
socket
import
socket
,
SOCK_STREAM
,
AF_INET6
,
SOL_SOCKET
,
SO_REUSEADDR
from
typon
import
fork
from
python.builtins
import
eval
from
builtins
import
eval
#fork = lambda x: x()
#fork = lambda x: x()
BACKLOG
=
1024
BACKLOG
=
1024
...
@@ -25,21 +24,24 @@ def create_listening_socket(port):
...
@@ -25,21 +24,24 @@ def create_listening_socket(port):
return
sockfd
return
sockfd
def
handle_connection
(
connfd
):
def
handle_connection
(
connfd
):
buf
=
connfd
.
recv
(
1024
).
decode
(
"utf-8"
)
buf
:
str
=
connfd
.
recv
(
1024
).
decode
(
"utf-8"
)
resp
:
str
resp
:
str
if
not
buf
.
startswith
(
"GET /eval?e="
):
if
not
buf
.
startswith
(
"GET /eval?e="
):
resp
=
"Expression missing"
resp
=
"Expression missing"
else
:
else
:
http_pos
=
buf
.
find
(
"HTTP/1.1
\
r
\
n
"
)
http_pos
=
buf
.
find
(
"HTTP/1.1
\
r
\
n
"
)
s
=
"str("
+
buf
[
12
:
http_pos
-
1
]
+
")"
s
=
"str("
+
buf
[
12
:
http_pos
-
1
]
+
")"
resp
=
eval
(
s
,
{
"req"
:
buf
})
#resp = eval(s, {"req": buf})
context
=
{
"req"
:
buf
}
resp
=
eval
(
s
,
context
)
response
=
response_fmt
.
format
(
len
(
resp
),
resp
)
response
=
response_fmt
.
format
(
len
(
resp
),
resp
)
connfd
.
send
(
response
.
encode
(
"utf-8"
))
connfd
.
send
(
response
.
encode
(
"utf-8"
))
connfd
.
close
()
connfd
.
close
()
def
server_loop
(
sockfd
):
def
server_loop
(
sockfd
):
while
True
:
while
True
:
connfd
,
_
=
sockfd
.
accept
()
#connfd, _ = sockfd.accept()
connfd
=
sockfd
.
accept
()[
0
]
fork
(
lambda
:
handle_connection
(
connfd
))
fork
(
lambda
:
handle_connection
(
connfd
))
...
...
typon/trans/transpiler/phases/emit_cpp/expr.py
View file @
fe2492d6
...
@@ -345,19 +345,18 @@ class ExpressionVisitor(NodeVisitor):
...
@@ -345,19 +345,18 @@ class ExpressionVisitor(NodeVisitor):
def
visit_Dict
(
self
,
node
:
ast
.
Dict
)
->
Iterable
[
str
]:
def
visit_Dict
(
self
,
node
:
ast
.
Dict
)
->
Iterable
[
str
]:
def
visit_item
(
key
,
value
):
def
visit_item
(
key
,
value
):
yield
"
std::pair
{"
yield
"{"
yield
from
self
.
visit
(
key
)
yield
from
self
.
visit
(
key
)
yield
", "
yield
", "
yield
from
self
.
visit
(
value
)
yield
from
self
.
visit
(
value
)
yield
"}"
yield
"}"
if
node
.
keys
:
if
node
.
keys
:
#
yield from self.visit(node.type)
yield
from
self
.
visit
(
node
.
type
)
yield
"typon::TyDict("
#
yield "typon::TyDict("
yield
"{"
yield
"
(
{"
yield
from
join
(
", "
,
map
(
visit_item
,
node
.
keys
,
node
.
values
))
yield
from
join
(
", "
,
map
(
visit_item
,
node
.
keys
,
node
.
values
))
yield
"}"
yield
"})"
yield
")"
else
:
else
:
yield
from
self
.
visit
(
node
.
type
)
yield
from
self
.
visit
(
node
.
type
)
yield
"{}"
yield
"{}"
...
@@ -394,8 +393,10 @@ class ExpressionVisitor(NodeVisitor):
...
@@ -394,8 +393,10 @@ class ExpressionVisitor(NodeVisitor):
def
visit_unary_operation
(
self
,
op
,
operand
)
->
Iterable
[
str
]:
def
visit_unary_operation
(
self
,
op
,
operand
)
->
Iterable
[
str
]:
if
type
(
op
)
!=
str
:
if
type
(
op
)
!=
str
:
op
=
SYMBOLS
[
type
(
op
)]
op
=
SYMBOLS
[
type
(
op
)]
yield
"("
yield
op
yield
op
yield
from
self
.
prec
(
"unary"
).
visit
(
operand
)
yield
from
self
.
visit
(
operand
)
yield
")"
def
visit_IfExp
(
self
,
node
:
ast
.
IfExp
)
->
Iterable
[
str
]:
def
visit_IfExp
(
self
,
node
:
ast
.
IfExp
)
->
Iterable
[
str
]:
yield
"("
yield
"("
...
...
typon/trans/transpiler/phases/emit_cpp/function.py
View file @
fe2492d6
...
@@ -38,11 +38,16 @@ def emit_function(name: str, func: CallableInstanceType, base="function", gen_p=
...
@@ -38,11 +38,16 @@ def emit_function(name: str, func: CallableInstanceType, base="function", gen_p=
yield
rty
yield
rty
yield
" {"
yield
" {"
for
var
,
initval
in
func
.
block_data
.
scope
.
root_decls
.
items
():
for
var
,
initval
in
func
.
block_data
.
scope
.
root_decls
.
items
():
__TB_NODE__
=
initval
if
isinstance
(
initval
,
BaseType
):
yield
from
NodeVisitor
().
visit_BaseType
(
initval
)
else
:
yield
"typename std::remove_reference<decltype("
# TODO: duplicate code in visit_lvalue
yield
"typename std::remove_reference<decltype("
# TODO: duplicate code in visit_lvalue
yield
from
ExpressionVisitor
(
func
.
block_data
.
scope
,
mode
).
visit
(
initval
)
yield
from
ExpressionVisitor
(
func
.
block_data
.
scope
,
mode
).
visit
(
initval
)
yield
")>::type"
yield
")>::type"
yield
var
yield
var
yield
";"
yield
";"
__TB_NODE__
=
func
.
block_data
.
node
vis
=
BlockVisitor
(
func
.
block_data
.
scope
,
generator
=
mode
)
vis
=
BlockVisitor
(
func
.
block_data
.
scope
,
generator
=
mode
)
for
stmt
in
func
.
block_data
.
node
.
body
:
for
stmt
in
func
.
block_data
.
node
.
body
:
yield
from
vis
.
visit
(
stmt
)
yield
from
vis
.
visit
(
stmt
)
...
...
typon/trans/transpiler/phases/emit_cpp/module.py
View file @
fe2492d6
...
@@ -2,11 +2,13 @@ import ast
...
@@ -2,11 +2,13 @@ import ast
from
typing
import
Iterable
from
typing
import
Iterable
from
transpiler.phases.emit_cpp.class_
import
emit_class
from
transpiler.phases.emit_cpp.class_
import
emit_class
from
transpiler.phases.emit_cpp.function
import
emit_function
from
transpiler.phases.emit_cpp.expr
import
ExpressionVisitor
from
transpiler.phases.emit_cpp.visitors
import
NodeVisitor
from
transpiler.phases.emit_cpp.function
import
emit_function
,
BlockVisitor
from
transpiler.phases.emit_cpp.visitors
import
NodeVisitor
,
CoroutineMode
from
transpiler.phases.typing.modules
import
ModuleType
,
TyponModuleType
,
PythonModuleType
from
transpiler.phases.typing.modules
import
ModuleType
,
TyponModuleType
,
PythonModuleType
from
transpiler.phases.typing.types
import
CallableInstanceType
,
ClassTypeType
,
TypeVariable
,
BaseType
,
GenericType
,
\
from
transpiler.phases.typing.types
import
CallableInstanceType
,
ClassTypeType
,
TypeVariable
,
BaseType
,
GenericType
,
\
GenericInstanceType
,
UserGenericType
GenericInstanceType
,
UserGenericType
,
RuntimeValue
from
transpiler.utils
import
linenodata
def
emit_module
(
mod
:
ModuleType
)
->
Iterable
[
str
]:
def
emit_module
(
mod
:
ModuleType
)
->
Iterable
[
str
]:
...
@@ -24,7 +26,7 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
...
@@ -24,7 +26,7 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
case
TyponModuleType
():
case
TyponModuleType
():
yield
f"#include <python/
{
name
}
.hpp>"
yield
f"#include <python/
{
name
}
.hpp>"
case
PythonModuleType
():
case
PythonModuleType
():
yield
f"namespace py_
{
name
}
{{"
yield
f"namespace py_
python_
{
name
}
{{"
yield
"template <typename _Unused = void>"
yield
"template <typename _Unused = void>"
yield
f"struct
{
name
}
__oo : referencemodel::moduletype<
{
name
}
__oo<>> {{"
yield
f"struct
{
name
}
__oo : referencemodel::moduletype<
{
name
}
__oo<>> {{"
...
@@ -75,25 +77,44 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
...
@@ -75,25 +77,44 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
case
ast
.
Import
(
names
):
case
ast
.
Import
(
names
):
for
alias
in
names
:
for
alias
in
names
:
yield
from
emit
(
alias
.
module_obj
)
yield
from
emit
(
alias
.
module_obj
)
incl_vars
.
append
(
f"auto&
{
alias
.
asname
or
alias
.
name
}
= py_
{
alias
.
name
}
::all;"
)
prefix
=
"python_"
if
isinstance
(
alias
.
module_obj
,
PythonModuleType
)
else
""
incl_vars
.
append
(
f"auto&
{
alias
.
asname
or
alias
.
name
}
= py_
{
prefix
}{
alias
.
module_obj
.
name
()
}
::all;"
)
case
ast
.
ImportFrom
(
module
,
names
,
_
):
case
ast
.
ImportFrom
(
module
,
names
,
_
):
yield
from
emit
(
node
.
module_obj
)
yield
from
emit
(
node
.
module_obj
)
prefix
=
"python_"
if
isinstance
(
node
.
module_obj
,
PythonModuleType
)
else
""
for
alias
in
names
:
for
alias
in
names
:
incl_vars
.
append
(
f"auto&
{
alias
.
asname
or
alias
.
name
}
= py_
{
module
}
::all.
{
alias
.
name
}
;"
)
if
isinstance
(
node
.
module_obj
,
PythonModuleType
):
if
isinstance
(
node
.
module_obj
.
fields
[
alias
.
name
].
type
.
resolve
(),
TypeVariable
):
continue
# unused function
incl_vars
.
append
(
f"auto&
{
alias
.
asname
or
alias
.
name
}
= py_
{
prefix
}{
node
.
module_obj
.
name
()
}
::all.
{
alias
.
name
}
;"
)
yield
"namespace PROGRAMNS {"
yield
"namespace PROGRAMNS {"
yield
from
incl_vars
yield
from
incl_vars
yield
"template <typename _Unused = void>"
yield
"template <typename _Unused = void>"
yield
f"struct
{
mod
.
name
()
}
__oo : referencemodel::moduletype<
{
mod
.
name
()
}
__oo<>>"
yield
f"struct
{
mod
.
name
()
}
__oo : referencemodel::moduletype<
{
mod
.
name
()
}
__oo<>>"
yield
"{"
yield
"{"
init_lines
=
[]
for
name
,
field
in
mod
.
fields
.
items
():
for
name
,
field
in
mod
.
fields
.
items
():
if
not
field
.
in_class_def
:
if
not
field
.
in_class_def
:
continue
continue
if
isinstance
(
field
.
type
,
ClassTypeType
):
ty
=
field
.
type
.
inner_type
else
:
ty
=
field
.
type
ty
=
field
.
type
if
isinstance
(
field
.
from_node
,
ast
.
Assign
):
yield
"static inline"
yield
from
NodeVisitor
().
visit_BaseType
(
field
.
from_node
.
value
.
type
)
yield
name
yield
"="
yield
from
ExpressionVisitor
(
mod
.
block_data
.
scope
,
CoroutineMode
.
SYNC
).
visit
(
field
.
from_node
.
value
)
yield
";"
# if not isinstance(field.from_node.value, RuntimeValue):
# assign_node = ast.Assign([ast.Name(name)], field.from_node.value, None, **linenodata(field.from_node))
# assign_node.is_declare = None
# init_lines.append(BlockVisitor(mod.block_data.scope).visit(assign_node))
continue
if
isinstance
(
ty
,
ClassTypeType
):
ty
=
ty
.
inner_type
gen_p
=
[
TypeVariable
(
p
.
name
,
emit_as_is
=
True
)
for
p
in
ty
.
parameters
]
gen_p
=
[
TypeVariable
(
p
.
name
,
emit_as_is
=
True
)
for
p
in
ty
.
parameters
]
ty
=
ty
.
instantiate
(
gen_p
)
ty
=
ty
.
instantiate
(
gen_p
)
from
transpiler.phases.typing.expr
import
ScoperExprVisitor
from
transpiler.phases.typing.expr
import
ScoperExprVisitor
...
@@ -109,7 +130,12 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
...
@@ -109,7 +130,12 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
case
_
:
case
_
:
raise
NotImplementedError
(
f"Unsupported module item type
{
ty
}
"
)
raise
NotImplementedError
(
f"Unsupported module item type
{
ty
}
"
)
yield
f"
{
mod
.
name
()
}
__oo() {{"
for
line
in
init_lines
:
yield
from
line
yield
"}"
yield
"};"
yield
"};"
yield
f"
constexpr
{
mod
.
name
()
}
__oo<>
{
mod
.
name
()
}
;"
yield
f"
{
mod
.
name
()
}
__oo<>
{
mod
.
name
()
}
;"
yield
f"static_assert(sizeof
{
mod
.
name
()
}
== 1);"
yield
f"static_assert(sizeof
{
mod
.
name
()
}
== 1);"
yield
"}"
yield
"}"
typon/trans/transpiler/phases/emit_cpp/visitors.py
View file @
fe2492d6
...
@@ -73,6 +73,8 @@ class NodeVisitor(UniversalVisitor):
...
@@ -73,6 +73,8 @@ class NodeVisitor(UniversalVisitor):
yield
'decltype(""_ps)'
yield
'decltype(""_ps)'
case
types
.
TY_LIST
:
case
types
.
TY_LIST
:
yield
"typon::TyList__oo<>::Obj"
yield
"typon::TyList__oo<>::Obj"
case
types
.
TY_DICT
:
yield
"typon::TyDict__oo<>::Obj"
case
types
.
TypeVariable
(
name
,
emit_as_is
=
em
,
decltype_str
=
dt
):
case
types
.
TypeVariable
(
name
,
emit_as_is
=
em
,
decltype_str
=
dt
):
if
em
:
if
em
:
yield
name
yield
name
...
...
typon/trans/transpiler/phases/typing/block.py
View file @
fe2492d6
...
@@ -115,8 +115,10 @@ class ScoperBlockVisitor(ScoperVisitor):
...
@@ -115,8 +115,10 @@ class ScoperBlockVisitor(ScoperVisitor):
# return True
# return True
val
=
val
or
RuntimeValue
()
val
=
val
or
RuntimeValue
()
self
.
scope
.
function
.
vars
[
target
.
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
decl_val
,
val
)
self
.
scope
.
function
.
vars
[
target
.
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
decl_val
,
val
)
if
self
.
scope
.
kind
==
ScopeKind
.
FUNCTION_INNER
:
#if self.scope.kind == ScopeKind.FUNCTION_INNER:
self
.
scope
.
function
.
root_decls
[
target
.
id
]
=
val
#if not isinstance(val, RuntimeValue):
if
True
:
self
.
scope
.
function
.
root_decls
[
target
.
id
]
=
val
if
not
isinstance
(
val
,
RuntimeValue
)
else
decl_val
return
False
return
False
return
True
return
True
elif
isinstance
(
target
,
ast
.
Tuple
):
elif
isinstance
(
target
,
ast
.
Tuple
):
...
...
typon/trans/transpiler/phases/typing/expr.py
View file @
fe2492d6
...
@@ -322,11 +322,14 @@ class ScoperExprVisitor(ScoperVisitor):
...
@@ -322,11 +322,14 @@ class ScoperExprVisitor(ScoperVisitor):
def
visit_Dict
(
self
,
node
:
ast
.
Dict
)
->
BaseType
:
def
visit_Dict
(
self
,
node
:
ast
.
Dict
)
->
BaseType
:
if
not
node
.
keys
:
if
not
node
.
keys
:
return
TY_DICT
.
instantiate_default
()
return
TY_DICT
.
instantiate_default
()
keys
=
[
self
.
visit
(
e
)
for
e
in
node
.
keys
]
key_type
=
TypeVariable
()
values
=
[
self
.
visit
(
e
)
for
e
in
node
.
values
]
value_type
=
TypeVariable
()
if
len
(
set
(
keys
))
!=
1
or
len
(
set
(
values
))
!=
1
:
for
k
,
v
in
zip
(
node
.
keys
,
node
.
values
):
raise
NotImplementedError
(
f"Dict with different types not handled yet in `
{
ast
.
unparse
(
node
)
}
`"
)
if
not
key_type
.
try_assign
(
self
.
visit
(
k
)):
return
TY_DICT
.
instantiate
([
keys
[
0
],
values
[
0
]])
raise
NotImplementedError
(
f"Dict with different key types not handled yet in `
{
ast
.
unparse
(
node
)
}
`"
)
if
not
value_type
.
try_assign
(
self
.
visit
(
v
)):
raise
NotImplementedError
(
f"Dict with different value types not handled yet in `
{
ast
.
unparse
(
node
)
}
`"
)
return
TY_DICT
.
instantiate
([
key_type
,
value_type
])
def
visit_Subscript
(
self
,
node
:
ast
.
Subscript
)
->
BaseType
:
def
visit_Subscript
(
self
,
node
:
ast
.
Subscript
)
->
BaseType
:
left
=
self
.
visit
(
node
.
value
)
left
=
self
.
visit
(
node
.
value
)
...
...
typon/trans/transpiler/phases/typing/modules.py
View file @
fe2492d6
...
@@ -23,7 +23,7 @@ def make_module(name: str, scope: Scope) -> TyponModuleType:
...
@@ -23,7 +23,7 @@ def make_module(name: str, scope: Scope) -> TyponModuleType:
return
name
return
name
ty
=
CreatedType
()
ty
=
CreatedType
()
for
n
,
v
in
scope
.
vars
.
items
():
for
n
,
v
in
scope
.
vars
.
items
():
ty
.
fields
[
n
]
=
MemberDef
(
v
.
type
,
v
.
val
,
v
.
is_item_decl
)
ty
.
fields
[
n
]
=
MemberDef
(
v
.
type
,
v
.
val
,
v
.
is_item_decl
,
v
.
from_node
)
return
ty
return
ty
visited_modules
=
{}
visited_modules
=
{}
...
@@ -62,6 +62,8 @@ def parse_module(mod_name: str, python_path: list[Path], scope=None, preprocess=
...
@@ -62,6 +62,8 @@ def parse_module(mod_name: str, python_path: list[Path], scope=None, preprocess=
"""
"""
if
mod_name
.
startswith
(
"python."
):
mod_name
=
mod_name
[
len
(
"python."
):]
try
:
try
:
py_mod
=
importlib
.
import_module
(
mod_name
)
py_mod
=
importlib
.
import_module
(
mod_name
)
except
ModuleNotFoundError
:
except
ModuleNotFoundError
:
...
...
typon/trans/transpiler/phases/typing/scope.py
View file @
fe2492d6
...
@@ -29,6 +29,7 @@ class VarDecl:
...
@@ -29,6 +29,7 @@ class VarDecl:
type
:
BaseType
type
:
BaseType
val
:
Any
=
RuntimeValue
()
val
:
Any
=
RuntimeValue
()
is_item_decl
:
bool
=
False
is_item_decl
:
bool
=
False
from_node
:
ast
.
AST
=
None
class
ScopeKind
(
Enum
):
class
ScopeKind
(
Enum
):
...
...
typon/trans/transpiler/phases/typing/stdlib.py
View file @
fe2492d6
...
@@ -102,7 +102,11 @@ class StdlibVisitor(NodeVisitorSeq):
...
@@ -102,7 +102,11 @@ class StdlibVisitor(NodeVisitorSeq):
self
.
visit
(
stmt
)
self
.
visit
(
stmt
)
def
visit_Assign
(
self
,
node
:
ast
.
Assign
):
def
visit_Assign
(
self
,
node
:
ast
.
Assign
):
self
.
scope
.
vars
[
node
.
targets
[
0
].
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
self
.
anno
().
visit
(
node
.
value
).
type_type
())
if
self
.
is_native
:
decl
=
VarDecl
(
VarKind
.
LOCAL
,
self
.
anno
().
visit
(
node
.
value
).
type_type
())
else
:
decl
=
VarDecl
(
VarKind
.
LOCAL
,
self
.
expr
().
visit
(
node
.
value
),
is_item_decl
=
True
,
from_node
=
node
)
self
.
scope
.
vars
[
node
.
targets
[
0
].
id
]
=
decl
def
visit_AnnAssign
(
self
,
node
:
ast
.
AnnAssign
):
def
visit_AnnAssign
(
self
,
node
:
ast
.
AnnAssign
):
ty
=
self
.
anno
().
visit
(
node
.
annotation
)
ty
=
self
.
anno
().
visit
(
node
.
annotation
)
...
...
typon/trans/transpiler/phases/typing/types.py
View file @
fe2492d6
...
@@ -24,6 +24,7 @@ class MemberDef:
...
@@ -24,6 +24,7 @@ class MemberDef:
type
:
"BaseType"
type
:
"BaseType"
val
:
typing
.
Any
=
RuntimeValue
()
val
:
typing
.
Any
=
RuntimeValue
()
in_class_def
:
bool
=
True
in_class_def
:
bool
=
True
from_node
:
ast
.
AST
=
None
@
dataclass
@
dataclass
class
UnifyMode
:
class
UnifyMode
:
...
...
typon/trans/we2.cpp
0 → 100644
View file @
fe2492d6
#include <python/builtins.hpp>
#include <python/socket.hpp>
#include <python/sys.hpp>
namespace
py_python_builtins
{
template
<
typename
_Unused
=
void
>
struct
builtins__oo
:
referencemodel
::
moduletype
<
builtins__oo
<>>
{
struct
:
referencemodel
::
function
{
auto
operator
()(
lvalue_or_rvalue
<
decltype
(
""
_ps
)
>
arg0
,
lvalue_or_rvalue
<
typon
::
TyDict__oo
<>::
Obj
<
decltype
(
""
_ps
),
decltype
(
""
_ps
)
>>
arg1
)
const
{
InterpGuard
guard
{};
try
{
return
py
::
module_
::
import
(
"builtins"
)
.
attr
(
"eval"
)(
*
arg0
,
*
arg1
)
.
cast
<
decltype
(
""
_ps
)
>
();
}
catch
(
py
::
error_already_set
&
e
)
{
std
::
cerr
<<
"Python exception: "
<<
e
.
what
()
<<
std
::
endl
;
throw
;
}
}
}
static
constexpr
eval
{};
};
builtins__oo
<>
all
;
}
// namespace py_python_builtins
namespace
PROGRAMNS
{
auto
&
sys
=
py_sys
::
all
;
auto
&
socket
=
py_socket
::
all
.
socket
;
auto
&
SOCK_STREAM
=
py_socket
::
all
.
SOCK_STREAM
;
auto
&
AF_INET6
=
py_socket
::
all
.
AF_INET6
;
auto
&
SOL_SOCKET
=
py_socket
::
all
.
SOL_SOCKET
;
auto
&
SO_REUSEADDR
=
py_socket
::
all
.
SO_REUSEADDR
;
auto
&
eval
=
py_python_builtins
::
all
.
eval
;
template
<
typename
_Unused
=
void
>
struct
webserver_eval__oo
:
referencemodel
::
moduletype
<
webserver_eval__oo
<>>
{
static
decltype
(
0
_pi
)
BACKLOG
;
static
decltype
(
0
_pi
)
PORT
;
static
decltype
(
""
_ps
)
response_fmt
;
struct
:
referencemodel
::
function
{
template
<
typename
AutoVar
$
9120453574589009546
=
void
,
typename
AutoVar
$
return
=
void
>
auto
typon
$$
sync
(
AutoVar
$
9120453574589009546
port
)
const
{
auto
sockfd
=
call_sync
(
socket
)(
AF_INET6
,
SOCK_STREAM
);
call_sync
(
dot
((
sockfd
),
setsockopt
))(
SOL_SOCKET
,
SO_REUSEADDR
,
1
_pi
);
call_sync
(
dot
((
sockfd
),
bind
))(
std
::
make_tuple
(
""
_ps
,
port
));
call_sync
(
dot
((
sockfd
),
listen
))(
BACKLOG
);
return
sockfd
;
}
using
has_sync
=
std
::
true_type
;
template
<
typename
AutoVar
$
9120453574589009546
=
void
,
typename
AutoVar
$
return
=
void
>
auto
operator
()(
AutoVar
$
9120453574589009546
port
)
const
->
typon
::
Task
<
decltype
(
typon
$$
sync
(
port
))
>
{
auto
sockfd
=
co_await
(
socket
)(
AF_INET6
,
SOCK_STREAM
);
co_await
(
dot
((
sockfd
),
setsockopt
))(
SOL_SOCKET
,
SO_REUSEADDR
,
1
_pi
);
co_await
(
dot
((
sockfd
),
bind
))(
std
::
make_tuple
(
""
_ps
,
port
));
co_await
(
dot
((
sockfd
),
listen
))(
BACKLOG
);
co_return
sockfd
;
}
}
static
constexpr
create_listening_socket
{};
static_assert
(
HasSync
<
decltype
(
create_listening_socket
)
>
);
static_assert
(
sizeof
create_listening_socket
==
1
);
struct
:
referencemodel
::
function
{
template
<
typename
AutoVar
$
1818216228010231424
=
void
,
typename
AutoVar
$
return
=
void
>
auto
operator
()(
AutoVar
$
1818216228010231424
connfd
)
const
->
typon
::
Task
<
typon
::
TyNone
>
{
auto
buf
=
co_await
(
dot
((
co_await
(
dot
((
connfd
),
recv
))(
1024
_pi
)),
decode
))(
"utf-8"
_ps
);
if
((
!
co_await
(
dot
((
buf
),
startswith
))(
"GET /eval?e="
_ps
)))
{
auto
resp
=
"Expression missing"
_ps
;
}
else
{
auto
http_pos
=
co_await
(
dot
((
buf
),
find
))(
"HTTP/1.1
\r\n
"
_ps
);
auto
s
=
(
((
(
"str("
_ps
+
(
dot
(
buf
,
oo__getitem__oo
)(
typon
::
TySlice
(
12
_pi
,
(
(
http_pos
-
1
_pi
)),
None
)))))
+
")"
_ps
));
//auto resp = co_await (eval)(s, typon::TyDict({std::pair{"req"_ps, buf}}));
}
co_return
None
;
}
}
static
constexpr
handle_connection
{};
static_assert
(
sizeof
handle_connection
==
1
);
struct
:
referencemodel
::
function
{
template
<
typename
AutoVar
$
1872507998259318362
=
void
,
typename
AutoVar
$
return
=
void
>
auto
operator
()(
AutoVar
$
1872507998259318362
sockfd
)
const
->
typon
::
Join
<
typon
::
TyNone
>
{
while
(
typon
::
TyBool
(
true
))
{
auto
connfd
=
(
co_await
typon
::
constant_get
<
0
>
(
co_await
(
dot
((
sockfd
),
accept
))()));
co_await
typon
::
fork
(
handle_connection
(
connfd
));
}
co_return
None
;
}
}
static
constexpr
server_loop
{};
static_assert
(
sizeof
server_loop
==
1
);
struct
:
referencemodel
::
function
{
template
<
typename
AutoVar
$
return
=
void
>
auto
operator
()()
const
->
typon
::
Task
<
typon
::
TyNone
>
{
co_await
(
print
)(
"Serving on port"
_ps
,
PORT
);
co_await
(
print
)();
auto
sockfd
=
co_await
(
create_listening_socket
)(
PORT
);
co_await
(
server_loop
)(
sockfd
);
co_return
None
;
}
}
static
constexpr
main
{};
static_assert
(
sizeof
main
==
1
);
webserver_eval__oo
()
{
BACKLOG
=
1024
_pi
;
PORT
=
8000
_pi
;
response_fmt
=
"HTTP/1.0 200 OK
\r\n
Content-type: text/plain
\r\n
Content-length: {}
\r\n\r\n
{}"
_ps
;
}
};
webserver_eval__oo
<>
webserver_eval
;
static_assert
(
sizeof
webserver_eval
==
1
);
}
// namespace PROGRAMNS
#ifdef TYPON_EXTENSION
#else
typon
::
Root
root
()
{
co_await
dot
(
PROGRAMNS
::
webserver_eval
,
main
)();
}
int
main
(
int
argc
,
char
*
argv
[])
{
py_sys
::
all
.
argv
=
typon
::
TyList__oo
<>::
Obj
(
std
::
vector
<
typon
::
TyStr__oo
<>::
Obj
>
(
argv
,
argv
+
argc
));
root
().
call
();
}
#endif
\ 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