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
2e7eaeb0
Commit
2e7eaeb0
authored
Mar 05, 2024
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Continue work on generics
parent
a577191a
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
35 changed files
with
1254 additions
and
1009 deletions
+1254
-1009
typon/include/python/basedef.hpp
typon/include/python/basedef.hpp
+9
-12
typon/include/python/builtins.hpp
typon/include/python/builtins.hpp
+208
-174
typon/include/python/builtins/bool.hpp
typon/include/python/builtins/bool.hpp
+30
-4
typon/include/python/builtins/bytes.hpp
typon/include/python/builtins/bytes.hpp
+29
-4
typon/include/python/builtins/dict.hpp
typon/include/python/builtins/dict.hpp
+78
-5
typon/include/python/builtins/exception.hpp
typon/include/python/builtins/exception.hpp
+2
-2
typon/include/python/builtins/int.hpp
typon/include/python/builtins/int.hpp
+68
-87
typon/include/python/builtins/list.hpp
typon/include/python/builtins/list.hpp
+91
-35
typon/include/python/builtins/print.hpp
typon/include/python/builtins/print.hpp
+14
-12
typon/include/python/builtins/range.hpp
typon/include/python/builtins/range.hpp
+10
-10
typon/include/python/builtins/set.hpp
typon/include/python/builtins/set.hpp
+1
-1
typon/include/python/builtins/slice.hpp
typon/include/python/builtins/slice.hpp
+7
-4
typon/include/python/builtins/str.hpp
typon/include/python/builtins/str.hpp
+83
-6
typon/include/python/hashlib.hpp
typon/include/python/hashlib.hpp
+5
-7
typon/include/python/json.hpp
typon/include/python/json.hpp
+6
-5
typon/include/python/os.hpp
typon/include/python/os.hpp
+27
-33
typon/include/python/referencemodel.hpp
typon/include/python/referencemodel.hpp
+320
-479
typon/include/python/socket.hpp
typon/include/python/socket.hpp
+52
-42
typon/include/python/sys.hpp
typon/include/python/sys.hpp
+4
-8
typon/trans/tests/builtins_test.py
typon/trans/tests/builtins_test.py
+11
-7
typon/trans/tests/webserver.py
typon/trans/tests/webserver.py
+11
-8
typon/trans/transpiler/phases/desugar_compare/__init__.py
typon/trans/transpiler/phases/desugar_compare/__init__.py
+2
-1
typon/trans/transpiler/phases/emit_cpp/expr.py
typon/trans/transpiler/phases/emit_cpp/expr.py
+14
-11
typon/trans/transpiler/phases/emit_cpp/function.py
typon/trans/transpiler/phases/emit_cpp/function.py
+59
-12
typon/trans/transpiler/phases/emit_cpp/module.py
typon/trans/transpiler/phases/emit_cpp/module.py
+3
-1
typon/trans/transpiler/phases/emit_cpp/visitors.py
typon/trans/transpiler/phases/emit_cpp/visitors.py
+3
-1
typon/trans/transpiler/phases/emit_cpp2/consts.py
typon/trans/transpiler/phases/emit_cpp2/consts.py
+3
-3
typon/trans/transpiler/phases/typing/__init__.py
typon/trans/transpiler/phases/typing/__init__.py
+7
-2
typon/trans/transpiler/phases/typing/block.py
typon/trans/transpiler/phases/typing/block.py
+22
-13
typon/trans/transpiler/phases/typing/common.py
typon/trans/transpiler/phases/typing/common.py
+1
-0
typon/trans/transpiler/phases/typing/expr.py
typon/trans/transpiler/phases/typing/expr.py
+17
-11
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
+46
-6
typon/trans/transpiler/transpiler.py
typon/trans/transpiler/transpiler.py
+5
-2
No files found.
typon/include/python/basedef.hpp
View file @
2e7eaeb0
...
...
@@ -5,23 +5,19 @@
#ifndef TYPON_BASEDEF_HPP
#define TYPON_BASEDEF_HPP
template
<
typename
Self
>
class
TyBuiltin
{
template
<
typename
...
Args
>
auto
sync_wrapper
(
Args
&&
...
args
)
{
return
static_cast
<
Self
*>
(
this
)
->
sync
(
std
::
forward
<
Args
>
(
args
)...);
template
<
typename
Self
>
class
TyBuiltin
{
template
<
typename
...
Args
>
auto
sync_wrapper
(
Args
&&
...
args
)
{
return
static_cast
<
Self
*>
(
this
)
->
sync
(
std
::
forward
<
Args
>
(
args
)...);
}
public:
template
<
typename
...
Args
>
auto
operator
()(
Args
&&
...
args
)
->
decltype
(
sync_wrapper
(
std
::
forward
<
Args
>
(
args
)...)
)
{
auto
operator
()(
Args
&&
...
args
)
->
decltype
(
sync_wrapper
(
std
::
forward
<
Args
>
(
args
)...))
{
return
sync_wrapper
(
std
::
forward
<
Args
>
(
args
)...);
}
};
/*
struct method {};
...
...
@@ -50,9 +46,10 @@ auto dot_bind(Obj, Attr attr) {
return attr;
}
#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 dots(OBJ, NAME) [](auto && obj) -> auto { return std::remove_reference<decltype(obj)>::type::py_type::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 dots(OBJ, NAME) [](auto && obj) -> auto { return
std::remove_reference<decltype(obj)>::type::py_type::NAME; }(OBJ)
*/
...
...
typon/include/python/builtins.hpp
View file @
2e7eaeb0
...
...
@@ -25,18 +25,19 @@
#define _Args(...) __VA_ARGS__
#define COMMA() ,
#define METHOD(ret, name, args, ...) \
static constexpr struct name##_s
: referencemodel::method {
\
template <typename Self> ret operator() args const __VA_ARGS__
\
} name
{};
static constexpr struct name##_s \
: referencemodel::method{template <typename Self> ret operator()
\
args const __VA_ARGS__} name
{};
#define METHOD_GEN(gen, ret, name, args, ...) \
static constexpr struct name##_s : referencemodel::method { \
template <typename Self, _Args gen> ret operator() args const __VA_ARGS__ \
} name{};
#define METHOD_GEN(gen, ret, name, args, ...) \
static constexpr struct name##_s \
: referencemodel::method{ \
template <typename Self, _Args gen> ret operator() \
args const __VA_ARGS__} name {};
#define FUNCTION(ret, name, args, ...) \
struct : referencemodel::staticmethod {
\
ret operator() args const __VA_ARGS__
\
struct : referencemodel::staticmethod { \
ret operator() args const __VA_ARGS__ \
} static constexpr name{};
using
namespace
std
::
literals
;
...
...
@@ -61,46 +62,58 @@ template <PySmartPtr T> struct RealType<T> {
namespace
typon
{
//template <typename T> using TyObj = std::shared_ptr<typename RealType<T>::type>;
// template <typename T> using TyObj = std::shared_ptr<typename
// RealType<T>::type>;
template
<
typename
T
>
template
<
typename
T
>
class
TyObj
:
public
std
::
shared_ptr
<
typename
RealType
<
T
>::
type
>
{
public:
using
inner
=
typename
RealType
<
T
>::
type
;
/*template<typename... Args>
TyObj(Args&&... args) : std::shared_ptr<inner>(std::make_shared<inner>(std::forward<Args>(args)...)) {}*/
TyObj
()
:
std
::
shared_ptr
<
inner
>
()
{}
TyObj
(
std
::
nullptr_t
)
:
std
::
shared_ptr
<
inner
>
(
nullptr
)
{}
TyObj
(
inner
*
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
const
std
::
shared_ptr
<
inner
>
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
std
::
shared_ptr
<
inner
>
&&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
const
TyObj
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
TyObj
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
TyObj
&&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
&
operator
=
(
const
TyObj
&
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
TyObj
&
operator
=
(
TyObj
&&
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
TyObj
&
operator
=
(
std
::
nullptr_t
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
nullptr
);
return
*
this
;
}
TyObj
&
operator
=
(
inner
*
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
TyObj
&
operator
=
(
const
std
::
shared_ptr
<
inner
>
&
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
template
<
typename
U
>
TyObj
(
const
TyObj
<
U
>
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
/*template<typename... Args>
TyObj(Args&&... args) :
std::shared_ptr<inner>(std::make_shared<inner>(std::forward<Args>(args)...))
{}*/
TyObj
()
:
std
::
shared_ptr
<
inner
>
()
{}
TyObj
(
std
::
nullptr_t
)
:
std
::
shared_ptr
<
inner
>
(
nullptr
)
{}
TyObj
(
inner
*
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
const
std
::
shared_ptr
<
inner
>
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
std
::
shared_ptr
<
inner
>
&&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
const
TyObj
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
TyObj
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
(
TyObj
&&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
TyObj
&
operator
=
(
const
TyObj
&
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
TyObj
&
operator
=
(
TyObj
&&
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
TyObj
&
operator
=
(
std
::
nullptr_t
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
nullptr
);
return
*
this
;
}
TyObj
&
operator
=
(
inner
*
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
TyObj
&
operator
=
(
const
std
::
shared_ptr
<
inner
>
&
ptr
)
{
std
::
shared_ptr
<
inner
>::
operator
=
(
ptr
);
return
*
this
;
}
//TyObj(TyObj<U> &&ptr) : std::shared_ptr<inner>(ptr) {}
template
<
typename
U
>
TyObj
(
const
TyObj
<
U
>
&
ptr
)
:
std
::
shared_ptr
<
inner
>
(
ptr
)
{}
// TyObj(TyObj<U> &&ptr) : std::shared_ptr<inner>(ptr) {}
// using make_shared
/*template<class U>
TyObj(U&& other) : std::shared_ptr<inner>(std::make_shared<inner>(other)) {}*/
/*template<class U>
TyObj(U&& other) : std::shared_ptr<inner>(std::make_shared<inner>(other)) {}*/
template
<
class
U
>
bool
operator
==
(
const
TyObj
<
U
>
&
other
)
const
{
template
<
class
U
>
bool
operator
==
(
const
TyObj
<
U
>
&
other
)
const
{
// check null
if
(
this
->
get
()
==
other
.
get
())
{
return
true
;
...
...
@@ -113,8 +126,7 @@ public:
return
*
this
->
get
()
==
*
other
.
get
();
}
template
<
class
U
>
bool
operator
==
(
const
U
&
other
)
const
{
template
<
class
U
>
bool
operator
==
(
const
U
&
other
)
const
{
if
(
this
->
get
()
==
nullptr
)
{
return
false
;
}
...
...
@@ -122,49 +134,50 @@ public:
return
*
this
->
get
()
==
other
;
}
template
<
class
U
>
bool
py_is
(
const
TyObj
<
U
>
&
other
)
const
{
template
<
class
U
>
bool
py_is
(
const
TyObj
<
U
>
&
other
)
const
{
return
this
->
get
()
==
other
.
get
();
}
};
template
<
typename
T
,
typename
...
Args
>
auto
tyObj
(
Args
&&
...
args
)
->
TyObj
<
typename
RealType
<
T
>::
type
>
{
template
<
typename
T
,
typename
...
Args
>
auto
tyObj
(
Args
&&
...
args
)
->
TyObj
<
typename
RealType
<
T
>::
type
>
{
return
std
::
make_shared
<
typename
RealType
<
T
>::
type
>
(
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
T
,
typename
...
Args
>
auto
pyobj_agg
(
Args
&&
...
args
)
->
TyObj
<
T
>
{
return
std
::
make_shared
<
typename
RealType
<
T
>::
type
>
((
typename
RealType
<
T
>::
type
)
{
std
::
forward
<
Args
>
(
args
)...
});
template
<
typename
T
,
typename
...
Args
>
auto
pyobj_agg
(
Args
&&
...
args
)
->
TyObj
<
T
>
{
return
std
::
make_shared
<
typename
RealType
<
T
>::
type
>
(
(
typename
RealType
<
T
>::
type
){
std
::
forward
<
Args
>
(
args
)...});
}
class
TyNone
{
};
class
TyNone
{};
}
}
// namespace typon
// typon_len
template
<
typename
T
>
concept
PyIterator
=
requires
(
T
t
)
{
{
t
.
py_next
()
}
->
std
::
same_as
<
std
::
optional
<
T
>>
;
};
{
t
.
py_next
()
}
->
std
::
same_as
<
std
::
optional
<
T
>>
;
};
template
<
typename
T
>
concept
PyIterable
=
requires
(
T
t
)
{
{
t
.
py_iter
()
}
->
PyIterator
;
};
{
t
.
py_iter
()
}
->
PyIterator
;
};
template
<
PyIterable
T
,
PyIterator
U
>
U
iter
(
const
T
&
t
)
{
return
t
.
py_iter
();
}
template
<
typename
T
>
concept
CppSize
=
requires
(
const
T
&
t
)
{
{
t
.
size
()
}
->
std
::
same_as
<
size_t
>
;
};
{
t
.
size
()
}
->
std
::
same_as
<
size_t
>
;
};
template
<
typename
T
>
concept
PyLen
=
requires
(
const
T
&
t
)
{
{
t
.
py_len
()
}
->
std
::
same_as
<
size_t
>
;
};
{
t
.
py_len
()
}
->
std
::
same_as
<
size_t
>
;
};
template
<
CppSize
T
>
requires
(
!
PyLen
<
T
>
)
...
...
@@ -176,8 +189,10 @@ template <PyLen T> size_t len(const T &t) { return t.py_len(); }
template
<
typename
T
>
concept
PyNext
=
requires
(
T
t
)
{
{
t
.
py_next
()
}
->
std
::
same_as
<
std
::
optional
<
typename
T
::
value_type
>>
;
};
{
t
.
py_next
()
}
->
std
::
same_as
<
std
::
optional
<
typename
T
::
value_type
>>
;
};
struct
{
template
<
PyNext
T
>
...
...
@@ -193,8 +208,6 @@ std::ostream &operator<<(std::ostream &os, std::optional<T> const &opt) {
return
opt
?
os
<<
opt
.
value
()
:
os
<<
"None"
;
}
bool
is_cpp
()
{
return
true
;
}
static
constexpr
auto
PyNone
=
std
::
nullopt
;
#define system_error(err, message) \
...
...
@@ -203,8 +216,8 @@ static constexpr auto PyNone = std::nullopt;
throw fmt::system_error(err, message); \
} while (0)
// #include "builtins/complex.hpp"
#include "builtins/bool.hpp"
#include "builtins/complex.hpp"
#include "builtins/dict.hpp"
#include "builtins/int.hpp"
#include "builtins/list.hpp"
...
...
@@ -214,61 +227,72 @@ static constexpr auto PyNone = std::nullopt;
#include "builtins/slice.hpp"
#include "builtins/str.hpp"
struct
file_s
{
struct
py_type
{
METHOD
(
typon
::
Task
<
TyStr
>
,
read
,
(
Self
self
,
size_t
size
=
-
1
),
{
if
(
size
==
-
1
)
{
size
=
self
->
len
;
}
TyStr
buf
(
size
,
'\0'
);
int
nbytes
=
co_await
typon
::
io
::
read
(
self
->
fd
,
buf
.
data
(),
size
);
if
(
nbytes
<
0
)
{
system_error
(
-
nbytes
,
"read()"
);
}
buf
.
resize
(
nbytes
);
co_return
std
::
move
(
buf
);
})
METHOD
(
typon
::
Task
<
int
>
,
write
,
(
Self
self
,
const
std
::
string
&
buf
),
{
int
nbytes
=
co_await
typon
::
io
::
write
(
self
->
fd
,
buf
);
if
(
nbytes
<
0
)
{
system_error
(
-
nbytes
,
"write()"
)
;
}
co_return
nbytes
;
})
METHOD
(
typon
::
Task
<
void
>
,
close
,
(
Self
self
),
{
co_await
typon
::
io
::
close
(
self
->
fd
);
})
METHOD
(
typon
::
Task
<
void
>
,
flush
,
(
Self
self
),
{
co_await
typon
::
io
::
fsync
(
self
->
fd
);
})
py_type
(
int
fd
=
-
1
,
size_t
len
=
0
)
:
fd
(
fd
),
len
(
len
)
{}
py_type
(
const
py_type
&
other
)
:
fd
(
other
.
fd
),
len
(
other
.
len
)
{}
METHOD
(
auto
,
py_enter
,
(
Self
self
),
{
return
self
;
})
METHOD
(
typon
::
Task
<
bool
>
,
py_exit
,
(
Self
self
),
{
co_await
dotp
(
self
,
close
)();
co_return
true
;
})
auto
is_cpp
()
{
return
typon
::
TyBool
(
true
);
}
namespace
typon
{
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyFile__oo
:
classtype
<
_Base0
,
TyFile__oo
<>>
{
struct
:
method
{
Task
<
TyStr__oo
<>::
Obj
>
operator
()(
auto
self
,
size_t
size
=
-
1
)
{
if
(
size
==
-
1
)
{
size
=
self
->
len
;
}
std
::
string
buf
(
size
,
'\0'
);
int
nbytes
=
co_await
typon
::
io
::
read
(
self
->
fd
,
buf
.
data
(),
size
);
if
(
nbytes
<
0
)
{
system_error
(
-
nbytes
,
"read()"
);
}
buf
.
resize
(
nbytes
);
co_return
std
::
move
(
TyStr__oo
<>::
Obj
(
buf
)
);
}
}
static
constexpr
read
{}
;
struct
:
method
{
Task
<
TyInt__oo
<>::
Obj
>
operator
()(
auto
self
,
auto
buf
)
{
int
nbytes
=
co_await
typon
::
io
::
write
(
self
->
fd
,
buf
->
value
);
if
(
nbytes
<
0
)
{
system_error
(
-
nbytes
,
"write()"
);
}
co_return
TyInt
(
nbytes
);
}
}
static
constexpr
write
{};
struct
:
method
{
Task
<
void
>
operator
()(
auto
self
)
{
co_await
typon
::
io
::
close
(
self
->
fd
);
}
}
static
constexpr
close
{};
struct
:
method
{
Task
<
void
>
operator
()(
auto
self
)
{
co_await
typon
::
io
::
fsync
(
self
->
fd
);
}
}
static
constexpr
flush
{};
struct
Obj
:
value
<
TyStr__oo
<>
,
Obj
>
{
Obj
(
int
fd
=
-
1
,
size_t
len
=
0
)
:
fd
(
fd
),
len
(
len
)
{}
Obj
(
const
Obj
&
other
)
:
fd
(
other
.
fd
),
len
(
other
.
len
)
{}
int
fd
;
size_t
len
;
};
}
file
;
namespace
typon
{
using
PyFile
=
TyObj
<
decltype
(
file
)
::
py_type
>
;
}
struct
:
method
{
auto
operator
()(
auto
self
)
{
return
self
;
}
}
static
constexpr
__enter__
{};
typon
::
Task
<
typon
::
PyFile
>
open
(
const
TyStr
&
path
,
std
::
string_view
mode
)
{
const
char
*
path_c
=
path
.
c_str
();
struct
:
method
{
Task
<
bool
>
operator
()(
auto
self
)
{
co_await
dot
(
self
,
close
)();
co_return
true
;
}
}
static
constexpr
__exit__
{};
};
static
constexpr
TyFile__oo
<>
TyFile
{};
}
// namespace typon
typon
::
Task
<
typon
::
TyFile__oo
<>::
Obj
>
open
(
auto
path
,
std
::
string_view
mode
)
{
const
char
*
path_c
=
path
->
value
.
c_str
();
size_t
len
=
0
;
struct
statx
statxbuf
;
if
(
int
err
=
co_await
typon
::
io
::
statx
(
AT_FDCWD
,
path_c
,
0
,
STATX_SIZE
,
...
...
@@ -315,7 +339,7 @@ typon::Task<typon::PyFile> open(const TyStr &path, std::string_view mode) {
std
::
cerr
<<
path
<<
","
<<
flags
<<
std
::
endl
;
system_error
(
-
fd
,
"openat()"
);
}
co_return
typon
::
tyObj
<
typon
::
PyFile
>
(
fd
,
len
);
co_return
typon
::
TyFile__oo
<>::
Obj
(
fd
,
len
);
}
#include <typon/generator.hpp>
...
...
@@ -326,55 +350,61 @@ namespace py = pybind11;
#include <utility>
template
<
typename
Ref
>
struct
lvalue_or_rvalue
{
template
<
typename
Ref
>
struct
lvalue_or_rvalue
{
Ref
&&
ref
;
template
<
typename
Arg
>
constexpr
lvalue_or_rvalue
(
Arg
&&
arg
)
noexcept
:
ref
(
std
::
move
(
arg
))
{
}
constexpr
operator
Ref
&
()
const
&
noexcept
{
return
ref
;
}
constexpr
operator
Ref
&&
()
const
&&
noexcept
{
return
std
::
move
(
ref
);
}
constexpr
Ref
&
operator
*
()
const
noexcept
{
return
ref
;
}
constexpr
Ref
*
operator
->
()
const
noexcept
{
return
&
ref
;
}
constexpr
lvalue_or_rvalue
(
Arg
&&
arg
)
noexcept
:
ref
(
std
::
move
(
arg
))
{}
constexpr
operator
Ref
&
()
const
&
noexcept
{
return
ref
;
}
constexpr
operator
Ref
&&
()
const
&&
noexcept
{
return
std
::
move
(
ref
);
}
constexpr
Ref
&
operator
*
()
const
noexcept
{
return
ref
;
}
constexpr
Ref
*
operator
->
()
const
noexcept
{
return
&
ref
;
}
};
namespace
typon
{
template
<
class
...
Types
>
using
PyTuple
=
std
::
tuple
<
Types
...
>
;
template
<
class
...
Types
>
using
PyTuple
=
std
::
tuple
<
Types
...
>
;
}
template
<
typename
T
>
auto
&
iter_fix_ref
(
T
&
obj
)
{
return
obj
;
}
template
<
typename
T
>
auto
&
iter_fix_ref
(
T
&
obj
)
{
return
obj
;
}
template
<
PySmartPtr
T
>
auto
&
iter_fix_ref
(
T
&
obj
)
{
return
*
obj
;
}
template
<
PySmartPtr
T
>
auto
&
iter_fix_ref
(
T
&
obj
)
{
return
*
obj
;
}
namespace
std
{
template
<
class
T
>
auto
begin
(
std
::
shared_ptr
<
T
>
&
obj
)
{
return
dot
(
obj
,
begin
)();
}
template
<
class
T
>
auto
begin
(
std
::
shared_ptr
<
T
>
&
obj
)
{
return
dot
(
obj
,
begin
)();
}
template
<
class
T
>
auto
end
(
std
::
shared_ptr
<
T
>
&
obj
)
{
return
dot
(
obj
,
end
)();
}
}
}
// namespace std
template
<
typename
T
>
struct
AlwaysTrue
{
// (1)
constexpr
bool
operator
()(
const
T
&
)
const
{
return
true
;
}
template
<
typename
T
>
struct
AlwaysTrue
{
// (1)
constexpr
bool
operator
()(
const
T
&
)
const
{
return
true
;
}
};
template
<
typename
Seq
>
/*
template <typename Seq>
struct ValueTypeEx {
using
type
=
decltype
(
*
std
::
begin
(
std
::
declval
<
Seq
&>
()));
using type = decltype(*std::begin(std::declval<Seq>()));
};*/
// has ::iterator type
template
<
typename
T
>
struct
ValueType
{
using
type
=
typename
T
::
iterator
::
value_type
;
};
template
<
typename
T
>
concept
HasIterator
=
requires
(
T
t
)
{
typename
T
::
iterator
;
};
template
<
HasIterator
T
>
struct
ValueType
<
T
>
{
using
type
=
typename
T
::
iterator
::
value_type
;
};
// (2)
/*template <typename Map, typename Seq, typename Filt = AlwaysTrue<typename ValueTypeEx<Seq>::type>>
typon::Task< mapFilter(Map map, Seq seq, Filt filt = Filt()) {
/*template <typename Map, typename Seq, typename Filt = AlwaysTrue<typename
ValueTypeEx<Seq>::type>> typon::Task< mapFilter(Map map, Seq seq, Filt filt =
Filt()) {
//typedef typename Seq::value_type value_type;
using value_type = typename ValueTypeEx<Seq>::type;
...
...
@@ -389,49 +419,53 @@ typon::Task< mapFilter(Map map, Seq seq, Filt filt = Filt()) {
return typon::TyList(std::move(result));
}*/
#define MAP_FILTER(item, seq, map, filter) ({\
using value_type = typename ValueTypeEx<decltype(seq)>::type;\
value_type item;\
std::vector<decltype(map)> result{};\
for (auto item : seq) {\
if (filter) {\
result.push_back(map);\
}\
}\
typon::TyList(std::move(result));\
})
#define MAP_FILTER(item, seq, map, filter) \
({ \
using value_type = ValueType<decltype(seq)>::type; \
value_type item; \
std::vector<decltype(map)> result{}; \
for (auto item : seq) { \
if (filter) { \
result.push_back(map); \
} \
} \
typon::TyList(std::move(result)); \
})
namespace
PYBIND11_NAMESPACE
{
namespace
detail
{
template
<
typename
T
>
struct
type_caster
<
typon
::
Task
<
T
>>
{
using
type
=
typon
::
Task
<
T
>
;
using
res_conv
=
make_caster
<
T
>
;
public:
PYBIND11_TYPE_CASTER
(
type
,
const_name
(
"Task["
)
+
res_conv
::
name
+
const_name
(
"]"
));
template
<
typename
U
>
static
handle
cast
(
U
&&
src
,
return_value_policy
policy
,
handle
parent
)
{
return
res_conv
::
cast
(
std
::
forward
<
T
>
(
std
::
move
(
src
).
call
()),
policy
,
parent
);
}
};
}
}
template
<
typename
T
>
struct
type_caster
<
typon
::
Task
<
T
>>
{
using
type
=
typon
::
Task
<
T
>
;
using
res_conv
=
make_caster
<
T
>
;
public:
PYBIND11_TYPE_CASTER
(
type
,
const_name
(
"Task["
)
+
res_conv
::
name
+
const_name
(
"]"
));
template
<
typename
U
>
static
handle
cast
(
U
&&
src
,
return_value_policy
policy
,
handle
parent
)
{
return
res_conv
::
cast
(
std
::
forward
<
T
>
(
std
::
move
(
src
).
call
()),
policy
,
parent
);
}
};
}
// namespace detail
}
// namespace PYBIND11_NAMESPACE
#ifdef TYPON_EXTENSION
class
InterpGuard
{
PyThreadState
*
main
;
PyThreadState
*
sub
;
PyThreadState
*
main
;
PyThreadState
*
sub
;
public:
InterpGuard
()
{
/*main = PyThreadState_Get();
sub = Py_NewInterpreter();*/
}
InterpGuard
()
{
/*main = PyThreadState_Get();
sub = Py_NewInterpreter();*/
}
~
InterpGuard
()
{
/*Py_EndInterpreter(sub);
PyThreadState_Swap(main);*/
}
~
InterpGuard
()
{
/*Py_EndInterpreter(sub);
PyThreadState_Swap(main);*/
}
};
#else
using
InterpGuard
=
py
::
scoped_interpreter
;
...
...
typon/include/python/builtins/bool.hpp
View file @
2e7eaeb0
...
...
@@ -7,10 +7,36 @@
#include <ostream>
#include "print.hpp"
#include "../referencemodel.hpp"
#include "str.hpp"
template
<
>
void
print_to
<
bool
>
(
const
bool
&
x
,
std
::
ostream
&
s
)
{
s
<<
(
x
?
"True"
:
"False"
);
}
namespace
typon
{
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyBool__oo
:
classtype
<
_Base0
,
TyBool__oo
<>>
{
static
constexpr
std
::
string_view
name
=
"TyBool"
;
struct
:
method
{
auto
operator
()(
auto
self
)
const
{
return
TyStr
(
self
->
value
?
"True"
:
"False"
);
}
}
static
constexpr
oo__str__oo
{};
static
constexpr
auto
oo__repr__oo
=
oo__str__oo
;
struct
Obj
:
value
<
TyBool__oo
<>
,
Obj
>
{
bool
value
;
constexpr
Obj
(
bool
value
=
false
)
:
value
(
value
)
{}
constexpr
operator
bool
()
const
{
return
value
;
}
};
/*static constexpr Obj TRUE = Obj(true);
static constexpr Obj FALSE = Obj(false);*/
auto
operator
()(
bool
value
)
const
{
return
Obj
(
value
);
}
};
static
constexpr
TyBool__oo
<>
TyBool
{};
}
// namespace typon
#endif // TYPON_BOOL_HPP
typon/include/python/builtins/bytes.hpp
View file @
2e7eaeb0
...
...
@@ -5,7 +5,7 @@
#ifndef TYPON_BYTES_H
#define TYPON_BYTES_H
class
TyStr
;
/*
class TyStr;
class TyBytes : public std::string {
public:
...
...
@@ -16,12 +16,37 @@ public:
TyBytes(size_t count, char ch) : std::string(count, ch) {}
template <class InputIterator>
TyBytes
(
InputIterator
first
,
InputIterator
last
)
:
std
::
string
(
first
,
last
)
{}
TyBytes(InputIterator first, InputIterator last) : std::string(first, last) {}
//TyStr decode_inner(const std::string &encoding = "utf-8") const;
//
TyStr decode_inner(const std::string &encoding = "utf-8") const;
METHOD(TyStr, decode, (Self self, const std::string &encoding = "utf-8"), ;)
};*/
namespace
typon
{
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyBytes__oo
:
classtype
<
_Base0
,
TyBytes__oo
<>>
{
static
constexpr
std
::
string_view
name
=
"TyBytes"
;
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
Obj
(
dot
(
self
,
value
)
+
dot
(
other
,
value
));
}
}
static
constexpr
oo__add__oo
{};
struct
Obj
:
value
<
TyBytes__oo
<>
,
Obj
>
{
std
::
string
value
;
constexpr
Obj
()
:
value
()
{}
constexpr
Obj
(
std
::
string
value
)
:
value
(
value
)
{}
operator
std
::
string
()
const
{
return
value
;
}
};
auto
operator
()(
std
::
string
value
)
const
{
return
Obj
(
value
);
}
};
static
constexpr
TyBytes__oo
<>
TyBytes
{};
#endif // TYPON_BYTES_H
}
// namespace typon
#endif // TYPON_BYTES_H
typon/include/python/builtins/dict.hpp
View file @
2e7eaeb0
...
...
@@ -5,8 +5,8 @@
#ifndef TYPON_DICT_HPP
#define TYPON_DICT_HPP
#include <unordered_map>
#include <pybind11/stl.h>
#include <unordered_map>
/*
template <typename K, typename V>
...
...
@@ -87,7 +87,7 @@ TyDict(std::initializer_list<std::pair<K, V>>) -> TyDict<K, V>;*/
namespace
typon
{
template
<
typename
K
,
typename
V
>
class
TyDict
{
/*
template <typename K, typename V> class TyDict {
public:
TyDict(std::shared_ptr<std::unordered_map<K, V>> &&m) : _m(std::move(m)) {}
TyDict(std::unordered_map<K, V> &&m)
...
...
@@ -132,14 +132,87 @@ public:
private:
std::shared_ptr<std::unordered_map<K, V>> _m;
};*/
}
// namespace typon
/*namespace PYBIND11_NAMESPACE {
namespace detail {
template <typename K, typename V>
struct type_caster<typon::TyDict<K, V>>
: map_caster<typon::TyDict<K, V>, K, V> {};
} // namespace detail
} // namespace PYBIND11_NAMESPACE*/
namespace
typon
{
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyDict__oo
:
classtype
<
_Base0
,
TyDict__oo
<>>
{
struct
:
method
{
template
<
typename
Self
>
auto
operator
()(
Self
self
)
const
{
std
::
stringstream
s
;
s
<<
'{'
;
if
(
self
->
_m
->
size
()
>
0
)
{
s
<<
repr
(
self
->
_m
->
begin
()
->
first
)
->
value
;
s
<<
": "
;
s
<<
repr
(
self
->
_m
->
begin
()
->
second
)
->
value
;
for
(
auto
it
=
++
self
->
_m
->
begin
();
it
!=
self
->
_m
->
end
();
it
++
)
{
s
<<
", "
;
s
<<
repr
(
it
->
first
)
->
value
;
s
<<
": "
;
s
<<
repr
(
it
->
second
)
->
value
;
}
}
s
<<
'}'
;
return
typon
::
TyStr__oo
<>::
Obj
(
s
.
str
());
}
}
static
constexpr
oo__repr__oo
{};
static
constexpr
auto
oo__str__oo
=
oo__repr__oo
;
template
<
typename
K
,
typename
V
>
struct
Obj
:
instance
<
TyDict__oo
<>
,
Obj
<
K
,
V
>>
{
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
::
unordered_map
<
K
,
V
>
&&
m
)
:
_m
(
std
::
move
(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>>
(
std
::
move
(
m
))))
{}
Obj
(
std
::
initializer_list
<
std
::
pair
<
K
,
V
>>
&&
m
)
:
_m
(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>>
(
std
::
move
(
m
)))
{}
Obj
()
:
_m
(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>>
())
{}
template
<
typename
...
Args
>
Obj
(
Args
&&
...
args
)
:
_m
(
std
::
make_shared
<
std
::
unordered_map
<
K
,
V
>>
(
std
::
forward
<
Args
>
(
args
)...))
{}
};
template
<
typename
T
>
auto
operator
()(
std
::
initializer_list
<
T
>
&&
v
)
const
{
return
rc
(
Obj
(
std
::
move
(
v
)));
}
template
<
typename
...
Args
>
auto
operator
()(
Args
&&
...
args
)
const
{
return
rc
(
Obj
(
std
::
forward
<
Args
>
(
args
)...));
}
};
}
static
constexpr
TyDict__oo
<>
TyDict
{};
}
// namespace typon
/*template <typename T> auto dict(std::initializer_list<T> &&v) {
return typon::TyDict(std::move(v));
}*/
namespace
PYBIND11_NAMESPACE
{
namespace
detail
{
template
<
typename
K
,
typename
V
>
struct
type_caster
<
typon
::
TyDict
<
K
,
V
>>
:
map_caster
<
typon
::
TyDict
<
K
,
V
>
,
K
,
V
>
{};
}}
struct
type_caster
<
typon
::
TyDict__oo
<>::
Obj
<
K
,
V
>>
:
map_caster
<
typon
::
TyDict__oo
<>::
Obj
<
K
,
V
>
,
K
,
V
>
{};
}
// namespace detail
}
// namespace PYBIND11_NAMESPACE
#endif // TYPON_DICT_HPP
typon/include/python/builtins/exception.hpp
View file @
2e7eaeb0
...
...
@@ -9,10 +9,10 @@
struct
TyException_s
{
struct
py_type
{
TyStr
message
;
TyStr
__oo
<>::
Obj
message
;
};
auto
operator
()(
const
TyStr
&
message
)
const
{
auto
operator
()(
const
TyStr
__oo
<>::
Obj
&
message
)
const
{
return
py_type
{
message
};
}
};
...
...
typon/include/python/builtins/int.hpp
View file @
2e7eaeb0
...
...
@@ -5,110 +5,98 @@
#ifndef TYPON_INT_HPP
#define TYPON_INT_HPP
#include <algorithm>
#include <sstream>
#include <string>
#include <algorithm>
using
namespace
std
::
literals
;
#include "bytes.hpp"
#include "print.hpp"
#include "slice.hpp"
#include "str.hpp"
// #include <format>
#include <fmt/format.h>
#include <pybind11/cast.h>
namespace
typon
{
/*template <typename _Base0 = object>
class TyInt__oo : classtype<_Base0, Integer__oo<>> {
public:
struct : method {
auto operator()(auto self, int value) const {
self->value = value;
}
} static constexpr oo__init__oo {};
struct : method {
auto operator()(auto self, auto other) const {
return Integer(dot(self, value) + dot(other, value));
}
} static constexpr oo__add__oo {};
auto operator () (int value) const {
struct Obj : instance<Integer__oo<>, Obj> {
int value;
};
auto obj = rc(Obj{});
dot(obj, oo__init__oo)(value);
return obj;
}
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyInt__oo
:
classtype
<
_Base0
,
TyInt__oo
<>>
{
static
constexpr
std
::
string_view
name
=
"TyInt"
;
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
Obj
(
dot
(
self
,
value
)
+
dot
(
other
,
value
));
}
}
static
constexpr
oo__add__oo
{};
constexpr TyInt(int value) : value(value) {}
constexpr TyInt() : value(0) {}
operator int() const { return value; }
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
Obj
(
dot
(
self
,
value
)
-
dot
(
other
,
value
));
}
}
static
constexpr
oo__sub__oo
{};
// operators
template <typename T> TyInt operator+(T x) const { return value + x; }
template <typename T> TyInt operator-(T x) const { return value - x; }
template <typename T> TyInt operator*(T x) const { return value * x; }
template <typename T> TyInt operator/(T x) const { return value / x; }
template <typename T> TyInt operator%(T x) const { return value % x; }
template <typename T> TyInt operator&(T x) const { return value & x; }
template <typename T> TyInt operator|(T x) const { return value | x; }
template <typename T> TyInt operator^(T x) const { return value ^ x; }
template <typename T> TyInt operator<<(T x) const { return value << x; }
template <typename T> TyInt operator>>(T x) const { return value >> x; }
template <typename T> TyInt operator&&(T x) const { return value && x; }
template <typename T> TyInt operator||(T x) const { return value || x; }
template <typename T> TyInt operator==(T x) const { return value == x; }
template <typename T> TyInt operator<(T x) const { return value < x; }
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
Obj
(
dot
(
self
,
value
)
*
dot
(
other
,
value
));
}
}
static
constexpr
oo__mul__oo
{};
TyInt operator-() const { return -value; }
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
Obj
(
dot
(
self
,
value
)
&
dot
(
other
,
value
));
}
}
static
constexpr
oo__and__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
)
const
{
return
Obj
(
-
dot
(
self
,
value
));
}
}
static
constexpr
oo__neg__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
dot
(
self
,
value
)
<
dot
(
other
,
value
);
}
}
static
constexpr
oo__lt__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
dot
(
self
,
value
)
>
dot
(
other
,
value
);
}
}
static
constexpr
oo__gt__oo
{};
private:
int value;
};*/
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
Integer__oo
:
classtype
<
_Base0
,
Integer__oo
<>>
{
static
constexpr
std
::
string_view
name
=
"Integer"
;
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
TyInt
(
dot
(
self
,
value
)
%
dot
(
other
,
value
));
}
}
static
constexpr
oo__mod__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
,
int
value
)
const
{
self
->
value
=
value
;
}
}
static
constexpr
oo__init__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
dot
(
self
,
value
)
>=
dot
(
other
,
value
)
;
}
}
static
constexpr
oo__ge__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
TyInt
(
dot
(
self
,
value
)
+
dot
(
other
,
value
));
}
}
static
constexpr
oo__add__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
)
const
{
return
TyStr__oo
<>::
Obj
(
std
::
to_string
(
self
->
value
));
}
}
static
constexpr
oo__str__oo
{};
struct
Obj
:
value
<
Integer__oo
<>
,
Obj
>
{
int
value
;
static
constexpr
auto
oo__repr__oo
=
oo__str__oo
;
Obj
(
int
value
=
0
)
:
value
(
value
)
{}
operator
int
()
const
{
return
value
;
}
};
struct
Obj
:
value
<
TyInt__oo
<>
,
Obj
>
{
int
value
;
auto
operator
()
(
int
value
)
const
{
auto
obj
=
rc
(
Obj
{});
dot
(
obj
,
oo__init__oo
)(
value
);
return
obj
;
}
Obj
(
int
value
=
0
)
:
value
(
value
)
{}
operator
int
()
const
{
return
value
;
}
};
static
constexpr
Integer__oo
<>
TyInt
{};
}
auto
operator
()(
int
value
)
const
{
return
Obj
(
value
);
}
};
static
constexpr
TyInt__oo
<>
TyInt
{};
}
// namespace typon
inline
auto
operator
""
_pi
(
unsigned
long
long
int
v
)
noexcept
{
inline
auto
operator
""
_pi
(
unsigned
long
long
int
v
)
noexcept
{
return
typon
::
TyInt
(
v
);
}
...
...
@@ -120,15 +108,8 @@ template <> struct std::hash<decltype(0_pi)> {
namespace
PYBIND11_NAMESPACE
{
namespace
detail
{
template
<
>
struct
type_caster
<
decltype
(
0
_pi
)
>
:
type_caster
<
int
>
{};
}}
template
<
>
void
repr_to
(
const
decltype
(
0
_pi
)
&
x
,
std
::
ostream
&
s
)
{
s
<<
x
;
}
template
<
>
void
print_to
<
decltype
(
0
_pi
)
>
(
const
decltype
(
0
_pi
)
&
x
,
std
::
ostream
&
s
)
{
s
<<
x
;
}
template
<
>
struct
type_caster
<
decltype
(
0
_pi
)
>
:
type_caster
<
int
>
{};
}
// namespace detail
}
// namespace PYBIND11_NAMESPACE
#endif // TYPON_INT_HPP
typon/include/python/builtins/list.hpp
View file @
2e7eaeb0
...
...
@@ -8,14 +8,90 @@
#include <algorithm>
#include <ostream>
#include <vector>
//#include <nanobind/stl/detail/nb_list.h>
//
#include <nanobind/stl/detail/nb_list.h>
#include <pybind11/stl.h>
namespace
typon
{
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyList__oo
:
classtype
<
_Base0
,
TyList__oo
<>>
{
template
<
typename
T
>
class
TyList
{
public:
using
value_type
=
T
;
struct
:
method
{
template
<
typename
Self
>
auto
operator
()(
Self
self
)
const
{
return
TyList__oo
<>
{}(
self
->
_v
);
}
}
static
constexpr
copy
{};
struct
:
method
{
template
<
typename
Self
,
typename
Other
>
auto
operator
()(
Self
self
,
Other
other
)
const
{
self
->
_v
.
reserve
(
self
->
_v
.
size
()
+
other
.
size
());
self
->
_v
.
insert
(
self
->
_v
.
end
(),
other
.
begin
(),
other
.
end
());
}
}
static
constexpr
extend
{};
struct
:
method
{
template
<
typename
Self
,
typename
Other
>
auto
operator
()(
Self
self
,
Other
other
)
const
{
auto
result
=
TyList__oo
<>
{}(
self
->
_v
);
dot
(
result
,
extend
)(
other
);
return
result
;
}
}
static
constexpr
oo__add__oo
{};
struct
:
method
{
template
<
typename
Self
,
typename
Other
>
auto
operator
()(
Self
self
,
Other
other
)
const
{
auto
result
=
TyList__oo
<>
{}(
self
->
_v
);
result
->
_v
->
reserve
(
result
->
_v
->
size
()
*
other
);
for
(
int
i
=
0
;
i
<
other
-
1
;
i
++
)
{
dot
(
result
,
extend
)(
self
);
}
return
result
;
}
}
static
constexpr
oo__mul__oo
{};
struct
:
method
{
template
<
typename
Self
>
auto
operator
()(
Self
self
)
const
{
std
::
stringstream
s
;
s
<<
'['
;
if
(
self
->
_v
->
size
()
>
0
)
{
s
<<
repr
(
self
->
_v
->
operator
[](
0
))
->
value
;
for
(
size_t
i
=
1
;
i
<
self
->
_v
->
size
();
i
++
)
{
s
<<
", "
;
s
<<
repr
(
self
->
_v
->
operator
[](
i
))
->
value
;
}
}
s
<<
']'
;
return
typon
::
TyStr__oo
<>::
Obj
(
s
.
str
());
}
}
static
constexpr
oo__repr__oo
{};
static
constexpr
auto
oo__str__oo
=
oo__repr__oo
;
template
<
typename
T
>
struct
Obj
:
instance
<
TyList__oo
<>
,
Obj
<
T
>>
{
using
value_type
=
T
;
std
::
shared_ptr
<
std
::
vector
<
T
>>
_v
;
Obj
(
std
::
shared_ptr
<
std
::
vector
<
T
>>
&&
v
)
:
_v
(
std
::
move
(
v
))
{}
Obj
(
std
::
vector
<
T
>
&&
v
)
:
_v
(
std
::
move
(
std
::
make_shared
<
std
::
vector
<
T
>>
(
std
::
move
(
v
))))
{}
Obj
(
std
::
initializer_list
<
T
>
&&
v
)
:
_v
(
std
::
make_shared
<
std
::
vector
<
T
>>
(
std
::
move
(
v
)))
{}
Obj
()
:
_v
(
std
::
make_shared
<
std
::
vector
<
T
>>
())
{}
};
template
<
typename
T
>
auto
operator
()(
std
::
initializer_list
<
T
>
&&
v
)
const
{
return
rc
(
Obj
(
std
::
move
(
v
)));
}
template
<
typename
...
Args
>
auto
operator
()(
Args
&&
...
args
)
const
{
return
rc
(
Obj
(
std
::
forward
<
Args
>
(
args
)...));
}
/*
TyList(std::shared_ptr<std::vector<T>> &&v) : _v(std::move(v)) {}
TyList(std::vector<T> &&v)
: _v(std::move(std::make_shared<std::vector<T>>(std::move(v)))) {}
...
...
@@ -41,7 +117,7 @@ public:
void push_back(const T &value) { _v->push_back(value); }
void
clear
()
{
_v
->
clear
();
}
void clear() { _v->clear(); }
*/
/*operator std::vector<T>() const {
return std::vector<T>(this->begin(), this->end());
...
...
@@ -51,7 +127,7 @@ public:
return *reinterpret_cast<std::vector<T> *>(this);
}*/
constexpr
const
T
&
operator
[](
size_t
i
)
const
{
return
_v
->
operator
[](
i
);
}
/*
constexpr const T &operator[](size_t i) const { return _v->operator[](i); }
constexpr T &operator[](size_t i) { return _v->operator[](i); }
size_t py_len() const { return _v->size(); }
...
...
@@ -68,44 +144,24 @@ public:
s << ']';
}
void
py_print
(
std
::
ostream
&
s
)
const
{
py_repr
(
s
);
}
TyList
<
T
>
operator
+
(
const
TyList
<
T
>
&
other
)
const
{
std
::
vector
<
T
>
v
;
v
.
reserve
(
_v
->
size
()
+
other
.
_v
->
size
());
v
.
insert
(
v
.
end
(),
_v
->
begin
(),
_v
->
end
());
v
.
insert
(
v
.
end
(),
other
.
_v
->
begin
(),
other
.
_v
->
end
());
return
TyList
<
T
>
(
std
::
move
(
v
));
}
TyList
<
T
>
operator
*
(
size_t
n
)
const
{
TyList
<
T
>
v
{};
v
.
_v
->
reserve
(
this
->
_v
->
size
()
*
n
);
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
{
v
.
_v
->
insert
(
v
.
_v
->
end
(),
this
->
_v
->
begin
(),
this
->
_v
->
end
());
}
return
v
;
}
private:
std
::
shared_ptr
<
std
::
vector
<
T
>>
_v
;
void py_print(std::ostream &s) const { py_repr(s); }*/
};
static
constexpr
TyList__oo
<>
TyList
{};
}
// namespace typon
}
template
<
typename
T
>
typon
::
TyList
<
T
>
list
(
std
::
initializer_list
<
T
>
&&
v
)
{
return
typon
::
TyList
<
T
>
(
std
::
move
(
v
));
template
<
typename
T
>
auto
list
(
std
::
initializer_list
<
T
>
&&
v
)
{
return
typon
::
TyList
(
std
::
move
(
v
));
}
namespace
PYBIND11_NAMESPACE
{
namespace
detail
{
template
<
typename
Type
>
struct
type_caster
<
typon
::
TyList
<
Type
>>
:
list_caster
<
typon
::
TyList
<
Type
>
,
Type
>
{};
}}
struct
type_caster
<
typon
::
TyList__oo
<>::
Obj
<
Type
>>
:
list_caster
<
typon
::
TyList__oo
<>::
Obj
<
Type
>
,
Type
>
{};
}
// namespace detail
}
// namespace PYBIND11_NAMESPACE
/*NAMESPACE_BEGIN(NB_NAMESPACE)
NAMESPACE_BEGIN(detail)
...
...
typon/include/python/builtins/print.hpp
View file @
2e7eaeb0
...
...
@@ -5,12 +5,12 @@
#ifndef TYPON_PRINT_HPP
#define TYPON_PRINT_HPP
#include <functional>
#include <iostream>
#include <ostream>
#include <functional>
#include <typon/typon.hpp>
template
<
typename
T
>
/*
template <typename T>
concept Streamable = requires(const T &x, std::ostream &s) {
{ s << x } -> std::same_as<std::ostream &>;
};
...
...
@@ -42,14 +42,14 @@ concept Printable = requires(const T &x, std::ostream &s) {
template <typename T>
concept Reprable = requires(const T &x, std::ostream &s) {
{ repr_to(x, s) } -> std::same_as<void>;
};
};
*/
template
<
typename
T
>
concept
FunctionPointer
=
std
::
is_function_v
<
T
>
or
std
::
is_member_function_pointer_v
<
T
>
or
std
::
is_function_v
<
std
::
remove_pointer_t
<
T
>>
;
template
<
Streamable
T
>
/*
template <Streamable T>
requires(FunctionPointer<T>)
void repr_to(const T &x, std::ostream &s) {
s << "<function at 0x" << std::hex << (size_t)x << std::dec << ">";
...
...
@@ -57,7 +57,8 @@ void repr_to(const T &x, std::ostream &s) {
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
s << "<function at 0x" << std::hex << (size_t)x.template target<T*>() <<
std::dec
<< ">";
}
...
...
@@ -75,7 +76,7 @@ void print_to(const std::shared_ptr<T> &x, std::ostream &s) {
template <Reprable T>
void repr_to(const std::shared_ptr<T> &x, std::ostream &s) {
repr_to(*x, s);
}
}
*/
/*
template <Printable T, Printable... Args>
...
...
@@ -86,18 +87,19 @@ typon::Task<void> print(T const &head, Args const &...args) {
}*/
struct
{
typon
::
TyNone
operator
()()
{
std
::
cout
<<
'\n'
;
return
{};
}
typon
::
TyNone
operator
()()
{
std
::
cout
<<
'\n'
;
return
{};
}
template
<
Printable
T
,
Printabl
e
...
Args
>
template
<
typename
T
,
typenam
e
...
Args
>
typon
::
TyNone
operator
()(
T
const
&
head
,
Args
const
&
...
args
)
{
print_to
(
head
,
std
::
cout
)
;
(((
std
::
cout
<<
' '
),
print_to
(
args
,
std
::
cout
)),
...);
std
::
cout
<<
str
(
head
)
->
value
;
(((
std
::
cout
<<
' '
),
(
std
::
cout
<<
str
(
args
)
->
value
)),
...);
std
::
cout
<<
'\n'
;
return
{};
}
}
print
;
// typon::Task<void> print() { std::cout << '\n'; co_return; }
#endif // TYPON_PRINT_HPP
typon/include/python/builtins/range.hpp
View file @
2e7eaeb0
...
...
@@ -12,30 +12,30 @@ namespace view = std::views;
#include <python/basedef.hpp>
auto
stride
=
[](
int
n
)
{
return
[
s
=
-
1
,
n
](
auto
const
&
)
mutable
{
s
=
(
s
+
1
)
%
n
;
return
!
s
;
};
return
[
s
=
-
1
,
n
](
auto
const
&
)
mutable
{
s
=
(
s
+
1
)
%
n
;
return
!
s
;
};
};
// todo: proper range support
struct
range_s
:
TyBuiltin
<
range_s
>
{
struct
range_s
:
TyBuiltin
<
range_s
>
{
auto
sync
(
int
start
,
int
stop
,
int
step
=
1
)
{
// https://www.modernescpp.com/index.php/c-20-pythons-map-function/
if
(
step
==
0
)
{
if
(
step
==
0
)
{
throw
std
::
invalid_argument
(
"Step cannot be 0"
);
}
auto
Step
=
start
<
stop
?
step
:
-
step
;
auto
Begin
=
std
::
min
(
start
,
stop
);
auto
End
=
Step
<
0
?
Begin
:
std
::
max
(
start
,
stop
);
return
view
::
iota
(
Begin
,
End
)
|
view
::
filter
(
stride
(
std
::
abs
(
Step
)))
|
view
::
transform
([
start
,
stop
](
std
::
size_t
i
){
return
start
<
stop
?
i
:
stop
-
(
i
-
start
);
});
return
view
::
iota
(
Begin
,
End
)
|
view
::
filter
(
stride
(
std
::
abs
(
Step
)))
|
view
::
transform
([
start
,
stop
](
std
::
size_t
i
)
{
return
start
<
stop
?
i
:
stop
-
(
i
-
start
);
});
}
auto
sync
(
int
stop
)
{
return
sync
(
0
,
stop
);
}
}
range
;
#endif // TYPON_RANGE_HPP
typon/include/python/builtins/set.hpp
View file @
2e7eaeb0
...
...
@@ -71,7 +71,7 @@ public:
}
};
}
}
// namespace typon
template
<
typename
T
>
typon
::
TySet
<
T
>
set
(
std
::
initializer_list
<
T
>
&&
s
)
{
return
typon
::
TySet
<
T
>
(
std
::
move
(
s
));
...
...
typon/include/python/builtins/slice.hpp
View file @
2e7eaeb0
...
...
@@ -5,10 +5,10 @@
#ifndef TYPON_SLICE_HPP
#define TYPON_SLICE_HPP
#include <optional>
#include <utility>
#include <Python.h>
#include <optional>
#include <stdint.h>
#include <utility>
struct
TySlice
{
TySlice
()
=
default
;
...
...
@@ -17,7 +17,9 @@ struct TySlice {
TySlice
&
operator
=
(
const
TySlice
&
)
=
default
;
TySlice
&
operator
=
(
TySlice
&&
)
=
default
;
TySlice
(
std
::
optional
<
ssize_t
>
start
,
std
::
optional
<
ssize_t
>
stop
,
std
::
optional
<
ssize_t
>
step
)
:
start
(
start
),
stop
(
stop
),
step
(
step
)
{
TySlice
(
std
::
optional
<
ssize_t
>
start
,
std
::
optional
<
ssize_t
>
stop
,
std
::
optional
<
ssize_t
>
step
)
:
start
(
start
),
stop
(
stop
),
step
(
step
)
{
if
(
step
==
0
)
{
throw
std
::
runtime_error
(
"slice step cannot be zero"
);
}
...
...
@@ -52,7 +54,8 @@ struct TySlice {
res
.
stop
=
this
->
stop
.
value
();
}
auto
len
=
PySlice_AdjustIndices
(
seq_length
,
&
res
.
start
,
&
res
.
stop
,
res
.
step
);
auto
len
=
PySlice_AdjustIndices
(
seq_length
,
&
res
.
start
,
&
res
.
stop
,
res
.
step
);
return
{
len
,
res
};
}
...
...
typon/include/python/builtins/str.hpp
View file @
2e7eaeb0
...
...
@@ -5,20 +5,19 @@
#ifndef TYPON_STR_HPP
#define TYPON_STR_HPP
#include <algorithm>
#include <sstream>
#include <string>
#include <algorithm>
using
namespace
std
::
literals
;
#include "bytes.hpp"
#include "print.hpp"
#include "slice.hpp"
// #include <format>
#include <fmt/format.h>
#include <pybind11/cast.h>
class
TyStr
:
public
std
::
string
{
/*
class TyStr : public std::string {
public:
TyStr() : std::string() {}
TyStr(const std::string &s) : std::string(s) {}
...
...
@@ -108,8 +107,8 @@ inline constexpr TyStr operator""_ps(const char *s, size_t len) noexcept {
}
template<typename Self>
TyStr
TyBytes
::
decode_s
::
operator
()(
Self
self
,
const
std
::
string
&
encoding
)
const
{
return
TyStr
(
self
.
begin
(),
self
.
end
());
TyStr TyBytes::decode_s::operator()(Self self, const std::string &encoding)
const {
return TyStr(self.begin(), self.end());
}
template <typename T> TyStr str(const T &x) {
...
...
@@ -150,6 +149,84 @@ struct {
std::getline(std::cin, input);
return input;
}
}
input
;
} input;*/
namespace
typon
{
using
namespace
referencemodel
;
template
<
typename
_Base0
=
object
>
struct
TyStr__oo
:
classtype
<
_Base0
,
TyStr__oo
<>>
{
static
constexpr
std
::
string_view
name
=
"TyStr"
;
struct
:
method
{
auto
operator
()(
auto
self
,
auto
other
)
const
{
return
Obj
(
dot
(
self
,
value
)
+
dot
(
other
,
value
));
}
}
static
constexpr
oo__add__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
)
const
{
return
Obj
(
self
->
value
);
}
}
static
constexpr
oo__str__oo
{};
struct
:
method
{
auto
operator
()(
auto
self
)
const
{
return
Obj
(
fmt
::
format
(
"
\"
{}
\"
"
,
self
->
value
));
}
}
static
constexpr
oo__repr__oo
{};
struct
Obj
:
value
<
TyStr__oo
<>
,
Obj
>
{
std
::
string
value
;
constexpr
Obj
()
:
value
()
{}
constexpr
Obj
(
std
::
string
value
)
:
value
(
value
)
{}
operator
std
::
string
()
const
{
return
value
;
}
};
auto
operator
()(
std
::
string
value
)
const
{
return
Obj
(
value
);
}
};
static
constexpr
TyStr__oo
<>
TyStr
{};
}
// namespace typon
inline
constexpr
auto
operator
""
_ps
(
const
char
*
s
,
size_t
len
)
noexcept
{
return
typon
::
TyStr__oo
<>::
Obj
(
std
::
string
(
s
,
len
));
}
/*template <typename T> auto str(const T &x) { return dot(x, oo__str__oo)(); }
template <typename T>
concept NoStr = not requires(T x) { dot(x, oo__str__oo)(); };
template <NoStr T> auto str(const T &x) {
std::stringstream s;
s << x;
return typon::TyStr__oo<>::Obj(s.str());
}
*/
template
<
typename
T
>
concept
HasStr
=
requires
(
T
x
)
{
dot
(
x
,
oo__str__oo
)();
};
template
<
typename
T
>
concept
HasRepr
=
requires
(
T
x
)
{
dot
(
x
,
oo__repr__oo
)();
};
template
<
typename
T
>
auto
str
(
const
T
&
x
)
{
if
constexpr
(
HasStr
<
T
>
)
{
return
dot
(
x
,
oo__str__oo
)();
}
else
{
std
::
stringstream
s
;
s
<<
x
;
return
typon
::
TyStr__oo
<>::
Obj
(
s
.
str
());
}
}
template
<
typename
T
>
auto
repr
(
const
T
&
x
)
{
if
constexpr
(
HasRepr
<
T
>
)
{
return
dot
(
x
,
oo__repr__oo
)();
}
else
{
std
::
stringstream
s
;
s
<<
x
;
return
typon
::
TyStr__oo
<>::
Obj
(
s
.
str
());
}
}
#endif // TYPON_STR_HPP
typon/include/python/hashlib.hpp
View file @
2e7eaeb0
...
...
@@ -23,7 +23,7 @@ struct hashlib_t {
struct
py_type
{
py_type
(
TyObj
<
void
>
context
,
openssl_update
update
,
openssl_final
final
,
int
diglen
)
int
diglen
)
:
_context
(
context
),
_update
(
update
),
_final
(
final
),
_diglen
(
diglen
)
{
}
...
...
@@ -60,30 +60,28 @@ struct hashlib_t {
auto
ctx
=
tyObj
<
MD5_CTX
>
();
MD5_Init
(
ctx
.
get
());
return
tyObj
<
_Hash_s
>
(
ctx
,
(
openssl_update
)
MD5_Update
,
(
openssl_final
)
MD5_Final
,
MD5_DIGEST_LENGTH
);
(
openssl_final
)
MD5_Final
,
MD5_DIGEST_LENGTH
);
})
FUNCTION
(
auto
,
sha1
,
(),
{
auto
ctx
=
tyObj
<
SHA_CTX
>
();
SHA1_Init
(
ctx
.
get
());
return
tyObj
<
_Hash_s
>
(
ctx
,
(
openssl_update
)
SHA1_Update
,
(
openssl_final
)
SHA1_Final
,
SHA_DIGEST_LENGTH
);
(
openssl_final
)
SHA1_Final
,
SHA_DIGEST_LENGTH
);
})
FUNCTION
(
auto
,
sha256
,
(),
{
auto
ctx
=
tyObj
<
SHA256_CTX
>
();
SHA256_Init
(
ctx
.
get
());
return
tyObj
<
_Hash_s
>
(
ctx
,
(
openssl_update
)
SHA256_Update
,
(
openssl_final
)
SHA256_Final
,
SHA256_DIGEST_LENGTH
);
(
openssl_final
)
SHA256_Final
,
SHA256_DIGEST_LENGTH
);
})
FUNCTION
(
auto
,
sha512
,
(),
{
auto
ctx
=
tyObj
<
SHA512_CTX
>
();
SHA512_Init
(
ctx
.
get
());
return
tyObj
<
_Hash_s
>
(
ctx
,
(
openssl_update
)
SHA512_Update
,
(
openssl_final
)
SHA512_Final
,
SHA512_DIGEST_LENGTH
);
(
openssl_final
)
SHA512_Final
,
SHA512_DIGEST_LENGTH
);
})
}
all
;
...
...
typon/include/python/json.hpp
View file @
2e7eaeb0
...
...
@@ -9,11 +9,12 @@
namespace
py_json
{
struct
json_t
{
FUNCTION
(
template
<
typename
T
>
typon
::
Task
<
void
>
,
dump
,
(
const
T
&
x
,
typon
::
PyFile
&
fp
),
{
std
::
stringstream
ss
;
repr_to
(
x
,
ss
);
co_await
dotp
(
fp
,
write
)(
ss
.
str
());
})
FUNCTION
(
template
<
typename
T
>
typon
::
Task
<
void
>
,
dump
,
(
const
T
&
x
,
typon
::
PyFile
&
fp
),
{
std
::
stringstream
ss
;
repr_to
(
x
,
ss
);
co_await
dotp
(
fp
,
write
)(
ss
.
str
());
})
}
all
;
auto
&
get_all
()
{
return
all
;
}
...
...
typon/include/python/os.hpp
View file @
2e7eaeb0
...
...
@@ -21,8 +21,7 @@ int no_special(const struct dirent *d) {
namespace
py_os
{
struct
os_t
{
FUNCTION
(
auto
,
fsdecode
,
(
std
::
string
s
),
{
return
s
;
})
FUNCTION
(
auto
,
fsdecode
,
(
std
::
string
s
),
{
return
s
;
})
struct
Stat_Result_s
{
struct
py_type
{
...
...
@@ -64,8 +63,9 @@ struct os_t {
})
METHOD
(
auto
,
begin
,
(
Self
self
),
{
return
*
self
;
})
METHOD
(
auto
,
end
,
(
Self
self
),
{
return
py_type
(
self
->
basepath
,
self
->
namelist
,
self
->
n
,
self
->
n
);
})
METHOD
(
auto
,
end
,
(
Self
self
),
{
return
py_type
(
self
->
basepath
,
self
->
namelist
,
self
->
n
,
self
->
n
);
})
auto
operator
*
()
{
auto
name
=
TyStr
(
this
->
namelist
[
this
->
current
]
->
d_name
);
...
...
@@ -73,7 +73,7 @@ struct os_t {
}
py_type
(
const
TyStr
&
basepath
,
struct
dirent
**
namelist
,
int
n
,
int
current
=
0
)
int
current
=
0
)
:
basepath
(
basepath
),
namelist
(
namelist
),
n
(
n
),
current
(
current
)
{
if
(
this
->
basepath
[
this
->
basepath
.
size
()
-
1
]
!=
'/'
)
{
this
->
basepath
+=
'/'
;
...
...
@@ -95,31 +95,25 @@ struct os_t {
};
}
_Scandiriterator
;
FUNCTION
(
typon
::
Task
<
TyObj
<
Stat_Result_s
>>
,
stat
,
(
const
TyStr
&
path
),
{
const
char
*
path_c
=
path
.
c_str
();
struct
statx
statxbuf
;
if
(
int
err
=
co_await
typon
::
io
::
statx
(
AT_FDCWD
,
path_c
,
0
,
STATX_SIZE
,
&
statxbuf
))
{
system_error
(
-
err
,
"statx()"
);
}
co_return
TyObj
<
Stat_Result_s
>
(
new
Stat_Result_s
::
py_type
{
statxbuf
.
stx_mode
,
statxbuf
.
stx_ino
,
makedev
(
statxbuf
.
stx_dev_major
,
statxbuf
.
stx_dev_minor
),
statxbuf
.
stx_nlink
,
statxbuf
.
stx_uid
,
statxbuf
.
stx_gid
,
statxbuf
.
stx_size
,
statxbuf
.
stx_atime
.
tv_sec
+
statxbuf
.
stx_atime
.
tv_nsec
/
1e9
f
,
statxbuf
.
stx_mtime
.
tv_sec
+
statxbuf
.
stx_mtime
.
tv_nsec
/
1e9
f
,
statxbuf
.
stx_ctime
.
tv_sec
+
statxbuf
.
stx_ctime
.
tv_nsec
/
1e9
f
,
statxbuf
.
stx_blocks
,
statxbuf
.
stx_blksize
,
makedev
(
statxbuf
.
stx_rdev_major
,
statxbuf
.
stx_rdev_minor
),
0
,
statxbuf
.
stx_btime
.
tv_sec
+
statxbuf
.
stx_btime
.
tv_nsec
/
1e9
});
})
FUNCTION
(
typon
::
Task
<
TyObj
<
Stat_Result_s
>>
,
stat
,
(
const
TyStr
&
path
),
{
const
char
*
path_c
=
path
.
c_str
();
struct
statx
statxbuf
;
if
(
int
err
=
co_await
typon
::
io
::
statx
(
AT_FDCWD
,
path_c
,
0
,
STATX_SIZE
,
&
statxbuf
))
{
system_error
(
-
err
,
"statx()"
);
}
co_return
TyObj
<
Stat_Result_s
>
(
new
Stat_Result_s
::
py_type
{
statxbuf
.
stx_mode
,
statxbuf
.
stx_ino
,
makedev
(
statxbuf
.
stx_dev_major
,
statxbuf
.
stx_dev_minor
),
statxbuf
.
stx_nlink
,
statxbuf
.
stx_uid
,
statxbuf
.
stx_gid
,
statxbuf
.
stx_size
,
statxbuf
.
stx_atime
.
tv_sec
+
statxbuf
.
stx_atime
.
tv_nsec
/
1e9
f
,
statxbuf
.
stx_mtime
.
tv_sec
+
statxbuf
.
stx_mtime
.
tv_nsec
/
1e9
f
,
statxbuf
.
stx_ctime
.
tv_sec
+
statxbuf
.
stx_ctime
.
tv_nsec
/
1e9
f
,
statxbuf
.
stx_blocks
,
statxbuf
.
stx_blksize
,
makedev
(
statxbuf
.
stx_rdev_major
,
statxbuf
.
stx_rdev_minor
),
0
,
statxbuf
.
stx_btime
.
tv_sec
+
statxbuf
.
stx_btime
.
tv_nsec
/
1e9
});
})
FUNCTION
(
TyObj
<
_Scandiriterator_s
>
,
scandir
,
(
const
TyStr
&
path
),
{
const
char
*
path_c
=
path
.
c_str
();
...
...
@@ -146,8 +140,8 @@ auto &get_all() { return all; }
}
// namespace py_os
namespace
typon
{
using
PyStat_Result
=
TyObj
<
py_os
::
os_t
::
Stat_Result_s
>
;
using
Py_Scandiriterator
=
TyObj
<
py_os
::
os_t
::
_Scandiriterator_s
>
;
}
using
PyStat_Result
=
TyObj
<
py_os
::
os_t
::
Stat_Result_s
>
;
using
Py_Scandiriterator
=
TyObj
<
py_os
::
os_t
::
_Scandiriterator_s
>
;
}
// namespace typon
#endif // TYPON_OS_HPP
typon/include/python/referencemodel.hpp
View file @
2e7eaeb0
...
...
@@ -12,25 +12,19 @@
#include <type_traits>
#include <utility>
namespace
referencemodel
{
/* Object model forward declarations */
struct
object
;
template
<
typename
T
,
typename
O
>
struct
instance
;
template
<
typename
T
,
typename
O
>
struct
instance
;
template
<
typename
T
,
typename
O
>
struct
value
;
template
<
typename
T
,
typename
O
>
struct
value
;
template
<
typename
B
,
typename
T
>
struct
classtype
;
template
<
typename
B
,
typename
T
>
struct
classtype
;
template
<
typename
M
>
struct
moduletype
;
template
<
typename
M
>
struct
moduletype
;
struct
function
;
...
...
@@ -40,26 +34,19 @@ struct classmethod;
struct
staticmethod
;
template
<
typename
S
,
typename
F
>
struct
boundmethod
;
template
<
typename
S
,
typename
F
>
struct
boundmethod
;
/* Reference model forward declarations */
template
<
typename
T
>
struct
Pack
;
template
<
typename
T
>
struct
Pack
;
template
<
typename
T
>
struct
Rc
;
template
<
typename
T
>
struct
Rc
;
template
<
typename
T
>
struct
Arc
;
template
<
typename
T
>
struct
Arc
;
template
<
typename
T
>
struct
Box
;
template
<
typename
T
>
struct
Box
;
template
<
typename
T
>
struct
Ref
;
template
<
typename
T
>
struct
Ref
;
/* Meta-programming utilities */
...
...
@@ -67,148 +54,117 @@ namespace meta {
/* Meta-programming utilities: always_false */
template
<
typename
T
>
struct
always_false_s
{
constexpr
static
bool
value
{
false
};
template
<
typename
T
>
struct
always_false_s
{
constexpr
static
bool
value
{
false
};
};
template
<
typename
T
>
inline
constexpr
bool
always_false
=
always_false_s
<
T
>::
value
;
/* Meta-programming utilities: unwrap_one */
template
<
typename
T
>
struct
unwrap_one_s
{
template
<
typename
T
>
struct
unwrap_one_s
{
using
type
=
T
;
};
template
<
typename
T
>
struct
unwrap_one_s
<
Pack
<
T
>>
{
template
<
typename
T
>
struct
unwrap_one_s
<
Pack
<
T
>>
{
using
type
=
T
;
};
template
<
typename
T
>
struct
unwrap_one_s
<
Rc
<
T
>>
{
template
<
typename
T
>
struct
unwrap_one_s
<
Rc
<
T
>>
{
using
type
=
T
;
};
template
<
typename
T
>
struct
unwrap_one_s
<
Arc
<
T
>>
{
template
<
typename
T
>
struct
unwrap_one_s
<
Arc
<
T
>>
{
using
type
=
T
;
};
template
<
typename
T
>
struct
unwrap_one_s
<
Box
<
T
>>
{
template
<
typename
T
>
struct
unwrap_one_s
<
Box
<
T
>>
{
using
type
=
T
;
};
template
<
typename
T
>
struct
unwrap_one_s
<
Ref
<
T
>>
{
template
<
typename
T
>
struct
unwrap_one_s
<
Ref
<
T
>>
{
using
type
=
T
;
};
template
<
typename
T
>
using
unwrap_one
=
typename
unwrap_one_s
<
std
::
remove_cvref_t
<
T
>>::
type
;
/* Meta-programming utilities: unwrap_all */
template
<
typename
T
>
struct
unwrap_all_s
{
template
<
typename
T
>
struct
unwrap_all_s
{
using
type
=
unwrap_one
<
T
>
;
};
template
<
typename
T
>
struct
unwrap_all_s
<
Ref
<
Pack
<
T
>>>
{
template
<
typename
T
>
struct
unwrap_all_s
<
Ref
<
Pack
<
T
>>>
{
using
type
=
T
;
};
template
<
typename
T
>
struct
unwrap_all_s
<
Ref
<
Arc
<
T
>>>
{
template
<
typename
T
>
struct
unwrap_all_s
<
Ref
<
Arc
<
T
>>>
{
using
type
=
T
;
};
template
<
typename
T
>
struct
unwrap_all_s
<
Box
<
Pack
<
T
>>>
{
template
<
typename
T
>
struct
unwrap_all_s
<
Box
<
Pack
<
T
>>>
{
using
type
=
T
;
};
template
<
typename
T
>
using
unwrap_all
=
typename
unwrap_all_s
<
std
::
remove_cvref_t
<
T
>>::
type
;
/* Meta-programming utilities: unwrap_pack */
template
<
typename
T
>
struct
unwrap_pack_s
{
template
<
typename
T
>
struct
unwrap_pack_s
{
using
type
=
unwrap_all
<
T
>
;
};
template
<
typename
T
>
struct
unwrap_pack_s
<
Pack
<
T
>>
{
template
<
typename
T
>
struct
unwrap_pack_s
<
Pack
<
T
>>
{
using
type
=
Pack
<
T
>
;
};
template
<
typename
T
>
struct
unwrap_pack_s
<
Ref
<
Pack
<
T
>>>
{
template
<
typename
T
>
struct
unwrap_pack_s
<
Ref
<
Pack
<
T
>>>
{
using
type
=
Pack
<
T
>
;
};
template
<
typename
T
>
struct
unwrap_pack_s
<
Ref
<
Arc
<
T
>>>
{
template
<
typename
T
>
struct
unwrap_pack_s
<
Ref
<
Arc
<
T
>>>
{
using
type
=
Pack
<
T
>
;
};
template
<
typename
T
>
struct
unwrap_pack_s
<
Box
<
Pack
<
T
>>>
{
template
<
typename
T
>
struct
unwrap_pack_s
<
Box
<
Pack
<
T
>>>
{
using
type
=
Pack
<
T
>
;
};
template
<
typename
T
>
using
unwrap_pack
=
typename
unwrap_pack_s
<
std
::
remove_cvref_t
<
T
>>::
type
;
/* Meta-programming utilities for object model */
template
<
typename
T
>
concept
object
=
std
::
derived_from
<
unwrap_all
<
T
>
,
referencemodel
::
object
>
;
template
<
typename
T
>
concept
instance
=
std
::
derived_from
<
unwrap_all
<
T
>
,
referencemodel
::
instance
<
typename
unwrap_all
<
T
>::
type
,
unwrap_all
<
T
>>
>
;
referencemodel
::
instance
<
typename
unwrap_all
<
T
>::
type
,
unwrap_all
<
T
>>>
;
template
<
typename
T
>
concept
classtype
=
!
instance
<
T
>
&&
std
::
derived_from
<
unwrap_all
<
T
>
,
referencemodel
::
classtype
<
typename
unwrap_all
<
T
>::
base
,
typename
unwrap_all
<
T
>::
type
>
>
;
concept
classtype
=
!
instance
<
T
>
&&
std
::
derived_from
<
unwrap_all
<
T
>
,
referencemodel
::
classtype
<
typename
unwrap_all
<
T
>::
base
,
typename
unwrap_all
<
T
>::
type
>>
;
template
<
typename
F
>
concept
function
=
std
::
derived_from
<
F
,
referencemodel
::
function
>
;
template
<
typename
F
>
concept
method
=
std
::
derived_from
<
F
,
referencemodel
::
method
>
;
template
<
typename
F
>
concept
classmethod
=
std
::
derived_from
<
F
,
referencemodel
::
classmethod
>
;
template
<
typename
F
>
concept
staticmethod
=
std
::
derived_from
<
F
,
referencemodel
::
staticmethod
>
;
template
<
typename
T
>
struct
boundmethod_s
{
template
<
typename
T
>
struct
boundmethod_s
{
static
constexpr
bool
value
=
false
;
};
...
...
@@ -220,18 +176,14 @@ struct boundmethod_s<referencemodel::boundmethod<S, F>> {
template
<
typename
T
>
concept
boundmethod
=
boundmethod_s
<
std
::
remove_cvref_t
<
T
>>::
value
;
template
<
typename
T
>
struct
value_s
{
template
<
typename
T
>
struct
value_s
{
static
constexpr
bool
value
=
true
;
};
template
<
instance
T
>
struct
value_s
<
T
>
{
template
<
instance
T
>
struct
value_s
<
T
>
{
static
constexpr
bool
value
=
std
::
derived_from
<
unwrap_all
<
T
>
,
referencemodel
::
value
<
typename
unwrap_all
<
T
>::
type
,
unwrap_all
<
T
>>
>
;
unwrap_all
<
T
>
,
referencemodel
::
value
<
typename
unwrap_all
<
T
>::
type
,
unwrap_all
<
T
>>>
;
};
template
<
typename
S
,
typename
F
>
...
...
@@ -242,222 +194,175 @@ struct value_s<referencemodel::boundmethod<S, F>> {
template
<
typename
T
>
concept
value
=
value_s
<
std
::
remove_cvref_t
<
T
>>::
value
;
/* Meta-programming utilities: wrapped and unwrapped */
template
<
typename
T
>
concept
unwrapped
=
std
::
is_same_v
<
T
,
unwrap_one
<
T
>>
;
template
<
typename
T
>
concept
wrapped
=
!
unwrapped
<
T
>
;
concept
wrapped
=
!
unwrapped
<
T
>
;
/* Meta-programming utilities: wrapped_by */
template
<
typename
T
,
template
<
typename
>
typename
M
>
struct
wrapped_by_s
{
static
constexpr
bool
value
{
false
};
template
<
typename
T
,
template
<
typename
>
typename
M
>
struct
wrapped_by_s
{
static
constexpr
bool
value
{
false
};
};
template
<
typename
T
,
template
<
typename
>
typename
M
>
struct
wrapped_by_s
<
M
<
T
>
,
M
>
{
static
constexpr
bool
value
{
true
};
static
constexpr
bool
value
{
true
};
};
template
<
typename
T
,
template
<
typename
>
typename
M
>
concept
wrapped_by
=
wrapped_by_s
<
std
::
remove_cvref
<
T
>
,
M
>::
value
;
/* Meta-programming utilities: pack */
template
<
typename
T
>
struct
pack_s
{
template
<
typename
T
>
struct
pack_s
{
using
type
=
Pack
<
unwrap_all
<
T
>>
;
};
template
<
value
T
>
struct
pack_s
<
T
>
{
template
<
value
T
>
struct
pack_s
<
T
>
{
using
type
=
T
;
};
template
<
typename
T
>
using
pack
=
typename
pack_s
<
T
>::
type
;
template
<
typename
T
>
using
pack
=
typename
pack_s
<
T
>::
type
;
/* Meta-programming utilities: rc */
template
<
typename
T
>
struct
rc_s
{
template
<
typename
T
>
struct
rc_s
{
using
type
=
Rc
<
unwrap_all
<
T
>>
;
};
template
<
value
T
>
struct
rc_s
<
T
>
{
template
<
value
T
>
struct
rc_s
<
T
>
{
using
type
=
T
;
};
template
<
typename
T
>
using
rc
=
typename
rc_s
<
T
>::
type
;
template
<
typename
T
>
using
rc
=
typename
rc_s
<
T
>::
type
;
/* Meta-programming utilities: arc */
template
<
typename
T
>
struct
arc_s
{
template
<
typename
T
>
struct
arc_s
{
using
type
=
Arc
<
unwrap_all
<
T
>>
;
};
template
<
value
T
>
struct
arc_s
<
T
>
{
template
<
value
T
>
struct
arc_s
<
T
>
{
using
type
=
T
;
};
template
<
typename
T
>
using
arc
=
typename
arc_s
<
T
>::
type
;
template
<
typename
T
>
using
arc
=
typename
arc_s
<
T
>::
type
;
/* Meta-programming utilities: box */
template
<
typename
T
>
struct
box_s
{
template
<
typename
T
>
struct
box_s
{
using
type
=
Box
<
unwrap_pack
<
T
>>
;
};
template
<
value
T
>
struct
box_s
<
T
>
{
template
<
value
T
>
struct
box_s
<
T
>
{
using
type
=
T
;
};
template
<
typename
T
>
using
box
=
typename
box_s
<
T
>::
type
;
template
<
typename
T
>
using
box
=
typename
box_s
<
T
>::
type
;
/* Meta-programming utilities: ref */
template
<
typename
T
>
struct
ref_s
{
template
<
typename
T
>
struct
ref_s
{
using
type
=
Ref
<
unwrap_all
<
T
>>
;
};
template
<
value
T
>
struct
ref_s
<
T
>
{
template
<
value
T
>
struct
ref_s
<
T
>
{
using
type
=
T
;
};
template
<
typename
T
>
using
ref
=
typename
ref_s
<
T
>::
type
;
template
<
typename
T
>
using
ref
=
typename
ref_s
<
T
>::
type
;
/* Meta-programming utilities: borrow */
template
<
typename
T
>
struct
borrow_s
{
template
<
typename
T
>
struct
borrow_s
{
using
type
=
ref
<
T
>
;
};
template
<
typename
T
>
struct
borrow_s
<
Rc
<
T
>>
{
template
<
typename
T
>
struct
borrow_s
<
Rc
<
T
>>
{
using
type
=
Ref
<
Pack
<
T
>>
;
};
template
<
typename
T
>
struct
borrow_s
<
Ref
<
Pack
<
T
>>>
{
template
<
typename
T
>
struct
borrow_s
<
Ref
<
Pack
<
T
>>>
{
using
type
=
Ref
<
Pack
<
T
>>
;
};
template
<
typename
T
>
struct
borrow_s
<
Arc
<
T
>>
{
template
<
typename
T
>
struct
borrow_s
<
Arc
<
T
>>
{
using
type
=
Ref
<
Arc
<
T
>>
;
};
template
<
typename
T
>
struct
borrow_s
<
Ref
<
Arc
<
T
>>>
{
template
<
typename
T
>
struct
borrow_s
<
Ref
<
Arc
<
T
>>>
{
using
type
=
Ref
<
Arc
<
T
>>
;
};
template
<
typename
T
>
using
borrow
=
typename
borrow_s
<
std
::
remove_cvref_t
<
T
>>::
type
;
/* Meta-programming utilities: forward */
template
<
typename
T
>
struct
forward_s
{
template
<
typename
T
>
struct
forward_s
{
using
type
=
borrow
<
T
>
;
};
template
<
typename
T
>
struct
forward_s
<
Box
<
T
>
&&>
{
template
<
typename
T
>
struct
forward_s
<
Box
<
T
>
&&>
{
using
type
=
Box
<
T
>
;
};
template
<
typename
T
>
using
forward
=
typename
forward_s
<
T
>::
type
;
template
<
typename
T
>
using
forward
=
typename
forward_s
<
T
>::
type
;
/* Meta-programming utilities: recover */
template
<
typename
T
>
struct
recover_s
{
template
<
typename
T
>
struct
recover_s
{
using
type
=
T
;
};
template
<
value
T
>
struct
recover_s
<
T
>
{
template
<
value
T
>
struct
recover_s
<
T
>
{
using
type
=
T
;
};
template
<
typename
T
>
struct
recover_s
<
Ref
<
Pack
<
T
>>>
{
template
<
typename
T
>
struct
recover_s
<
Ref
<
Pack
<
T
>>>
{
using
type
=
Rc
<
T
>
;
};
template
<
typename
T
>
struct
recover_s
<
Ref
<
Arc
<
T
>>>
{
template
<
typename
T
>
struct
recover_s
<
Ref
<
Arc
<
T
>>>
{
using
type
=
Arc
<
T
>
;
};
template
<
typename
T
>
using
recover
=
typename
recover_s
<
std
::
remove_cvref_t
<
T
>>::
type
;
/* Meta-programming utilities: own */
template
<
typename
T
>
struct
own_s
{
template
<
typename
T
>
struct
own_s
{
using
type
=
recover
<
T
>
;
};
template
<
unwrapped
T
>
struct
own_s
<
Ref
<
T
>>
{
template
<
unwrapped
T
>
struct
own_s
<
Ref
<
T
>>
{
static_assert
(
always_false
<
T
>
,
"Ref<T> cannot be owned"
);
};
template
<
typename
T
>
using
own
=
typename
own_s
<
std
::
remove_cvref_t
<
T
>>::
type
;
template
<
typename
T
>
using
own
=
typename
own_s
<
std
::
remove_cvref_t
<
T
>>::
type
;
/* Meta-programming utilities: common_forward */
template
<
typename
...
>
struct
common_forward_s
{};
template
<
typename
...
>
struct
common_forward_s
{};
template
<
typename
...
T
>
using
common_forward
=
typename
common_forward_s
<
T
...
>::
type
;
template
<
typename
T
>
struct
common_forward_s
<
T
>
{
template
<
typename
T
>
struct
common_forward_s
<
T
>
{
using
type
=
forward
<
T
>
;
};
template
<
typename
T
,
typename
U
>
struct
common_forward_s
<
T
,
U
>
{
template
<
typename
T
,
typename
U
>
struct
common_forward_s
<
T
,
U
>
{
using
type
=
std
::
common_type_t
<
forward
<
T
>
,
forward
<
U
>>
;
};
template
<
typename
T
>
struct
common_forward_s
<
T
,
T
>
{
template
<
typename
T
>
struct
common_forward_s
<
T
,
T
>
{
using
type
=
forward
<
T
>
;
};
...
...
@@ -468,8 +373,8 @@ struct common_forward_s<T, U> {
};
template
<
instance
T
,
instance
U
>
requires
std
::
is_same_v
<
unwrap_all
<
T
>
,
unwrap_all
<
U
>>
&&
(
!
std
::
is_same_v
<
forward
<
T
>
,
forward
<
U
>>
)
requires
std
::
is_same_v
<
unwrap_all
<
T
>
,
unwrap_all
<
U
>>
&&
(
!
std
::
is_same_v
<
forward
<
T
>
,
forward
<
U
>>
)
struct
common_forward_s
<
T
,
U
>
{
static_assert
(
!
std
::
is_same_v
<
T
,
Box
<
unwrap_all
<
T
>>
&&>
);
static_assert
(
!
std
::
is_same_v
<
U
,
Box
<
unwrap_all
<
U
>>
&&>
);
...
...
@@ -481,69 +386,52 @@ struct common_forward_s<T, U, V...> {
using
type
=
common_forward
<
common_forward
<
T
,
U
>
,
V
...
>
;
};
}
// namespace meta
/* Conversion functions */
template
<
typename
T
>
auto
pack
(
T
&&
t
)
{
template
<
typename
T
>
auto
pack
(
T
&&
t
)
{
return
meta
::
pack
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
rc
(
T
&&
t
)
{
return
meta
::
rc
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
rc
(
T
&&
t
)
{
return
meta
::
rc
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
arc
(
T
&&
t
)
{
template
<
typename
T
>
auto
arc
(
T
&&
t
)
{
return
meta
::
arc
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
box
(
T
&&
t
)
{
template
<
typename
T
>
auto
box
(
T
&&
t
)
{
return
meta
::
box
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
ref
(
T
&&
t
)
{
template
<
typename
T
>
auto
ref
(
T
&&
t
)
{
return
meta
::
ref
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
borrow
(
T
&&
t
)
{
template
<
typename
T
>
auto
borrow
(
T
&&
t
)
{
return
meta
::
borrow
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
forward
(
T
&&
t
)
{
template
<
typename
T
>
auto
forward
(
T
&&
t
)
{
return
meta
::
forward
<
T
&&>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
recover
(
T
&&
t
)
{
template
<
typename
T
>
auto
recover
(
T
&&
t
)
{
return
meta
::
recover
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
template
<
typename
T
>
auto
own
(
T
&&
t
)
{
template
<
typename
T
>
auto
own
(
T
&&
t
)
{
return
meta
::
own
<
T
>
(
std
::
forward
<
T
>
(
t
));
}
/* Utilities: NonNull */
template
<
typename
T
>
struct
NonNull
{
template
<
typename
T
>
struct
NonNull
{
NonNull
()
=
default
;
NonNull
(
T
*
some
)
:
ptr
(
some
)
{
assert
(
ptr
);
};
NonNull
(
T
*
some
)
:
ptr
(
some
)
{
assert
(
ptr
);
};
NonNull
&
operator
=
(
const
T
*
some
)
{
NonNull
&
operator
=
(
const
T
*
some
)
{
ptr
=
some
;
assert
(
ptr
);
return
*
this
;
...
...
@@ -551,38 +439,36 @@ struct NonNull {
NonNull
(
std
::
nullptr_t
)
:
ptr
(
nullptr
)
{}
NonNull
&
operator
=
(
std
::
nullptr_t
)
{
NonNull
&
operator
=
(
std
::
nullptr_t
)
{
ptr
=
nullptr
;
return
*
this
;
}
T
*
operator
->
()
const
{
return
ptr
;
}
T
*
operator
->
()
const
{
return
ptr
;
}
operator
T
*
()
const
{
return
ptr
;
}
operator
T
*
()
const
{
return
ptr
;
}
operator
bool
()
const
{
return
ptr
;
}
operator
bool
()
const
{
return
ptr
;
}
private:
T
*
ptr
;
private:
T
*
ptr
;
};
/* Reference model */
template
<
typename
T
>
struct
Pack
{
template
<
typename
T
>
struct
Pack
{
static_assert
(
std
::
is_same_v
<
T
,
meta
::
unwrap_all
<
T
>>
);
static_assert
(
std
::
atomic_ref
<
std
::
uint32_t
>::
is_always_lock_free
);
Pack
()
=
default
;
Pack
(
T
&&
t
)
:
rc
(
1
),
value
(
std
::
move
(
t
))
{}
Pack
(
T
&&
t
)
:
rc
(
1
),
value
(
std
::
move
(
t
))
{}
Pack
(
Pack
&&
)
=
default
;
const
T
*
operator
->
()
const
{
return
std
::
addressof
(
value
);
}
const
T
*
operator
->
()
const
{
return
std
::
addressof
(
value
);
}
T
*
operator
->
()
{
return
std
::
addressof
(
value
);
}
T
*
operator
->
()
{
return
std
::
addressof
(
value
);
}
auto
read_count
()
const
{
return
rc
;
}
...
...
@@ -597,48 +483,42 @@ struct Pack {
friend
struct
Ref
<
Pack
>
;
friend
struct
Ref
<
Arc
<
T
>>
;
private:
std
::
uint32_t
rc
=
1
;
T
value
;
private:
std
::
uint32_t
rc
=
1
;
T
value
;
};
template
<
typename
T
>
struct
Rc
{
template
<
typename
T
>
struct
Rc
{
static_assert
(
std
::
is_same_v
<
T
,
meta
::
unwrap_all
<
T
>>
);
Rc
()
:
ptr
(
nullptr
)
{}
Rc
(
std
::
nullptr_t
)
:
ptr
(
nullptr
)
{}
Rc
(
T
&&
t
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
t
)))
{}
Rc
(
T
&&
t
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
t
)))
{}
Rc
(
Pack
<
T
>
&&
pack
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
pack
)))
{}
Rc
(
Pack
<
T
>
&&
pack
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
pack
)))
{}
Rc
(
Pack
<
T
>
&
pack
)
:
ptr
(
&
pack
)
{
ptr
->
rc
++
;
}
Rc
(
Pack
<
T
>
&
pack
)
:
ptr
(
&
pack
)
{
ptr
->
rc
++
;
}
Rc
(
Rc
&&
rc
)
:
ptr
(
std
::
exchange
(
rc
.
ptr
,
nullptr
))
{}
Rc
(
Rc
&&
rc
)
:
ptr
(
std
::
exchange
(
rc
.
ptr
,
nullptr
))
{}
Rc
(
const
Rc
&
rc
)
:
ptr
(
rc
.
ptr
)
{
ptr
->
rc
++
;
}
Rc
(
const
Rc
&
rc
)
:
ptr
(
rc
.
ptr
)
{
ptr
->
rc
++
;
}
Rc
(
const
Ref
<
Pack
<
T
>>
&
ref
)
:
ptr
(
ref
.
ptr
)
{
Rc
(
const
Ref
<
Pack
<
T
>>
&
ref
)
:
ptr
(
ref
.
ptr
)
{
assert
(
ptr
->
read_count
());
ptr
->
rc
++
;
}
Rc
(
Box
<
Pack
<
T
>>
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
Rc
(
Box
<
Pack
<
T
>>
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
assert
(
!
ptr
->
rc
++
);
}
Rc
(
Box
<
Pack
<
T
>>
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
Rc
(
Box
<
Pack
<
T
>>
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
assert
(
!
ptr
->
rc
++
);
}
Rc
&
operator
=
(
Rc
rc
)
{
Rc
&
operator
=
(
Rc
rc
)
{
std
::
swap
(
ptr
,
rc
.
ptr
);
return
*
this
;
}
...
...
@@ -651,7 +531,7 @@ struct Rc {
}
}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
auto
read_count
()
const
{
return
ptr
->
read_count
();
}
...
...
@@ -659,56 +539,54 @@ struct Rc {
friend
struct
Ref
<
T
>
;
friend
struct
Ref
<
Pack
<
T
>>
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
};
template
<
typename
T
>
struct
Arc
{
template
<
typename
T
>
struct
Arc
{
static_assert
(
std
::
is_same_v
<
T
,
meta
::
unwrap_all
<
T
>>
);
Arc
()
:
ptr
(
nullptr
)
{}
Arc
(
std
::
nullptr_t
)
:
ptr
(
nullptr
)
{}
Arc
(
T
&&
t
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
t
)))
{}
Arc
(
T
&&
t
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
t
)))
{}
Arc
(
Arc
&&
arc
)
:
ptr
(
std
::
exchange
(
arc
.
ptr
,
nullptr
))
{}
Arc
(
Arc
&&
arc
)
:
ptr
(
std
::
exchange
(
arc
.
ptr
,
nullptr
))
{}
Arc
(
const
Arc
&
arc
)
:
ptr
(
arc
.
ptr
)
{
Arc
(
const
Arc
&
arc
)
:
ptr
(
arc
.
ptr
)
{
std
::
atomic_ref
(
ptr
->
rc
).
fetch_add
(
1
,
std
::
memory_order_relaxed
);
}
Arc
(
const
Ref
<
Arc
<
T
>>
&
ref
)
:
ptr
(
ref
.
ptr
)
{
Arc
(
const
Ref
<
Arc
<
T
>>
&
ref
)
:
ptr
(
ref
.
ptr
)
{
assert
(
ptr
->
atomic_read_count
());
std
::
atomic_ref
(
ptr
->
rc
).
fetch_add
(
1
,
std
::
memory_order_relaxed
);
}
Arc
(
Box
<
Pack
<
T
>>
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
Arc
(
Box
<
Pack
<
T
>>
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
assert
(
!
std
::
atomic_ref
(
ptr
->
rc
).
fetch_add
(
1
,
std
::
memory_order_relaxed
));
}
Arc
(
Box
<
Pack
<
T
>>
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
Arc
(
Box
<
Pack
<
T
>>
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{
assert
(
!
std
::
atomic_ref
(
ptr
->
rc
).
fetch_add
(
1
,
std
::
memory_order_relaxed
));
}
Arc
&
operator
=
(
Arc
arc
)
{
Arc
&
operator
=
(
Arc
arc
)
{
std
::
swap
(
ptr
,
arc
.
ptr
);
return
*
this
;
}
~
Arc
()
{
if
(
ptr
)
{
// null only if (swapped with a) moved from or uninitialised Arc
if
(
std
::
atomic_ref
(
ptr
->
rc
).
fetch_sub
(
1
,
std
::
memory_order_release
)
==
1
)
{
if
(
std
::
atomic_ref
(
ptr
->
rc
).
fetch_sub
(
1
,
std
::
memory_order_release
)
==
1
)
{
std
::
atomic_thread_fence
(
std
::
memory_order_acquire
);
delete
ptr
;
}
}
}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
auto
read_count
()
const
{
return
ptr
->
atomic_read_count
();
}
...
...
@@ -716,26 +594,24 @@ struct Arc {
friend
struct
Ref
<
T
>
;
friend
struct
Ref
<
Arc
<
T
>>
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
};
template
<
typename
T
>
struct
Box
{
template
<
typename
T
>
struct
Box
{
static_assert
(
std
::
is_same_v
<
T
,
meta
::
unwrap_all
<
T
>>
);
Box
()
:
ptr
(
nullptr
)
{}
Box
(
std
::
nullptr_t
)
:
ptr
(
nullptr
)
{}
Box
(
T
&&
t
)
:
ptr
(
new
T
(
std
::
move
(
t
)))
{}
Box
(
T
&&
t
)
:
ptr
(
new
T
(
std
::
move
(
t
)))
{}
Box
(
Box
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
(
Box
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
(
Box
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
(
Box
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
&
operator
=
(
Box
box
)
{
Box
&
operator
=
(
Box
box
)
{
std
::
swap
(
ptr
,
box
.
ptr
);
return
*
this
;
}
...
...
@@ -746,43 +622,37 @@ struct Box {
}
}
T
*
operator
->
()
const
{
return
ptr
;
}
T
*
operator
->
()
const
{
return
ptr
;
}
friend
struct
Ref
<
T
>
;
private:
NonNull
<
T
>
ptr
;
private:
NonNull
<
T
>
ptr
;
};
template
<
typename
T
>
struct
Box
<
Pack
<
T
>>
{
template
<
typename
T
>
struct
Box
<
Pack
<
T
>>
{
Box
()
:
ptr
(
nullptr
)
{}
Box
(
std
::
nullptr_t
)
:
ptr
(
nullptr
)
{}
Box
(
T
&&
t
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
t
)))
{
assert
(
!--
(
ptr
->
rc
));
}
Box
(
T
&&
t
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
t
)))
{
assert
(
!--
(
ptr
->
rc
));
}
Box
(
Pack
<
T
>
&&
pack
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
pack
)))
{
Box
(
Pack
<
T
>
&&
pack
)
:
ptr
(
new
Pack
<
T
>
(
std
::
move
(
pack
)))
{
assert
(
!--
(
ptr
->
rc
));
}
Box
(
Rc
<
T
>
&&
rc
)
:
ptr
(
rc
.
ptr
)
{
assert
(
!--
(
ptr
->
rc
));
}
Box
(
Rc
<
T
>
&&
rc
)
:
ptr
(
rc
.
ptr
)
{
assert
(
!--
(
ptr
->
rc
));
}
Box
(
Arc
<
T
>
&&
rc
)
:
ptr
(
rc
.
ptr
)
{
assert
(
std
::
atomic_ref
(
ptr
->
rc
).
fetch_sub
(
1
,
std
::
memory_order_relaxed
)
==
1
);
Box
(
Arc
<
T
>
&&
rc
)
:
ptr
(
rc
.
ptr
)
{
assert
(
std
::
atomic_ref
(
ptr
->
rc
).
fetch_sub
(
1
,
std
::
memory_order_relaxed
)
==
1
);
}
Box
(
Box
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
(
Box
&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
(
Box
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
(
Box
&&
box
)
:
ptr
(
std
::
exchange
(
box
.
ptr
,
nullptr
))
{}
Box
&
operator
=
(
Box
box
)
{
Box
&
operator
=
(
Box
box
)
{
std
::
swap
(
ptr
,
box
.
ptr
);
return
*
this
;
}
...
...
@@ -793,153 +663,135 @@ struct Box<Pack<T>> {
}
}
T
*
operator
->
()
const
{
return
ptr
;
}
T
*
operator
->
()
const
{
return
ptr
;
}
friend
struct
Rc
<
T
>
;
friend
struct
Arc
<
T
>
;
friend
struct
Ref
<
T
>
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
};
template
<
typename
T
>
struct
Ref
{
template
<
typename
T
>
struct
Ref
{
static_assert
(
std
::
is_same_v
<
T
,
meta
::
unwrap_all
<
T
>>
);
Ref
()
=
default
;
Ref
(
T
&
t
)
:
ptr
(
std
::
addressof
(
t
))
{}
Ref
(
T
&
t
)
:
ptr
(
std
::
addressof
(
t
))
{}
Ref
(
const
Ref
&
)
=
default
;
Ref
(
Ref
&&
)
=
default
;
Ref
&
operator
=
(
Ref
ref
)
{
Ref
&
operator
=
(
Ref
ref
)
{
ptr
=
ref
.
ptr
;
return
*
this
;
}
Ref
(
Pack
<
T
>
&
pack
)
:
ptr
(
std
::
addressof
(
pack
.
value
))
{}
Ref
(
Pack
<
T
>
&
pack
)
:
ptr
(
std
::
addressof
(
pack
.
value
))
{}
Ref
(
const
Rc
<
T
>
&
rc
)
:
ptr
(
std
::
addressof
(
rc
.
ptr
->
value
))
{}
Ref
(
const
Rc
<
T
>
&
rc
)
:
ptr
(
std
::
addressof
(
rc
.
ptr
->
value
))
{}
Ref
(
const
Arc
<
T
>
&
arc
)
:
ptr
(
std
::
addressof
(
arc
.
ptr
->
value
))
{}
Ref
(
const
Arc
<
T
>
&
arc
)
:
ptr
(
std
::
addressof
(
arc
.
ptr
->
value
))
{}
Ref
(
const
Ref
<
Pack
<
T
>>
&
ref
)
:
ptr
(
std
::
addressof
(
ref
.
ptr
->
value
))
{}
Ref
(
const
Ref
<
Pack
<
T
>>
&
ref
)
:
ptr
(
std
::
addressof
(
ref
.
ptr
->
value
))
{}
Ref
(
const
Ref
<
Arc
<
T
>>
&
ref
)
:
ptr
(
std
::
addressof
(
ref
.
ptr
->
value
))
{}
Ref
(
const
Ref
<
Arc
<
T
>>
&
ref
)
:
ptr
(
std
::
addressof
(
ref
.
ptr
->
value
))
{}
Ref
(
const
Box
<
T
>
&
box
)
:
ptr
(
box
.
ptr
)
{}
Ref
(
const
Box
<
T
>
&
box
)
:
ptr
(
box
.
ptr
)
{}
Ref
(
const
Box
<
Pack
<
T
>>
&
box
)
:
ptr
(
box
.
ptr
)
{}
Ref
(
const
Box
<
Pack
<
T
>>
&
box
)
:
ptr
(
box
.
ptr
)
{}
T
*
operator
->
()
const
{
return
ptr
;
}
T
*
operator
->
()
const
{
return
ptr
;
}
private:
NonNull
<
T
>
ptr
;
private:
NonNull
<
T
>
ptr
;
};
template
<
typename
T
>
struct
Ref
<
Pack
<
T
>>
{
template
<
typename
T
>
struct
Ref
<
Pack
<
T
>>
{
Ref
()
=
default
;
Ref
(
Pack
<
T
>
&
pack
)
:
ptr
(
std
::
addressof
(
pack
))
{}
Ref
(
Pack
<
T
>
&
pack
)
:
ptr
(
std
::
addressof
(
pack
))
{}
Ref
(
const
Ref
&
)
=
default
;
Ref
(
Ref
&&
)
=
default
;
Ref
&
operator
=
(
Ref
ref
)
{
Ref
&
operator
=
(
Ref
ref
)
{
ptr
=
ref
.
ptr
;
return
*
this
;
}
Ref
(
const
Rc
<
T
>
&
rc
)
:
ptr
(
rc
.
ptr
)
{}
Ref
(
const
Rc
<
T
>
&
rc
)
:
ptr
(
rc
.
ptr
)
{}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
friend
struct
Rc
<
T
>
;
friend
struct
Ref
<
T
>
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
};
template
<
typename
T
>
struct
Ref
<
Arc
<
T
>>
{
template
<
typename
T
>
struct
Ref
<
Arc
<
T
>>
{
Ref
()
=
default
;
Ref
(
const
Ref
&
)
=
default
;
Ref
(
Ref
&&
)
=
default
;
Ref
&
operator
=
(
Ref
ref
)
{
Ref
&
operator
=
(
Ref
ref
)
{
ptr
=
ref
.
ptr
;
return
*
this
;
}
Ref
(
const
Arc
<
T
>
&
arc
)
:
ptr
(
arc
.
ptr
)
{}
Ref
(
const
Arc
<
T
>
&
arc
)
:
ptr
(
arc
.
ptr
)
{}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
T
*
operator
->
()
const
{
return
std
::
addressof
(
ptr
->
value
);
}
friend
struct
Arc
<
T
>
;
friend
struct
Ref
<
T
>
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
private:
NonNull
<
Pack
<
T
>>
ptr
;
};
template
<
typename
T
>
Ref
(
Rc
<
T
>
&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Rc
<
T
>
&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Rc
<
T
>
&&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Rc
<
T
>
&&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Arc
<
T
>
&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Arc
<
T
>
&&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Arc
<
T
>
&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Box
<
T
>
&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
template
<
typename
T
>
Ref
(
Arc
<
T
>
&&
)
->
Ref
<
T
>
;
template
<
typename
T
>
Ref
(
Box
<
T
>
&&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
template
<
typename
T
>
Ref
(
Box
<
T
>
&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
template
<
meta
::
wrapped
T
>
Ref
(
Ref
<
T
>
&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
template
<
typename
T
>
Ref
(
Box
<
T
>
&&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
template
<
meta
::
wrapped
T
>
Ref
(
Ref
<
T
>
&&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
template
<
meta
::
wrapped
T
>
Ref
(
Ref
<
T
>
&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
template
<
meta
::
wrapped
T
>
Ref
(
Ref
<
T
>
&&
)
->
Ref
<
meta
::
unwrap_all
<
T
>>
;
/* Equality */
template
<
typename
T
,
typename
U
>
requires
meta
::
wrapped
<
T
>
||
meta
::
wrapped
<
U
>
bool
operator
==
(
const
T
&
t
,
const
U
&
u
)
{
return
t
.
operator
->
()
==
u
.
operator
->
();
requires
meta
::
wrapped
<
T
>
||
meta
::
wrapped
<
U
>
bool
operator
==
(
const
T
&
t
,
const
U
&
u
)
{
return
t
.
operator
->
()
==
u
.
operator
->
();
}
namespace
meta
{
/* Compile-time string concatenation */
// taken from https://stackoverflow.com/a/62823211
template
<
std
::
string_view
const
&
...
Strs
>
struct
join_s
{
template
<
std
::
string_view
const
&
...
Strs
>
struct
join_s
{
// Join all strings into a single std::array of chars
static
constexpr
auto
impl
()
noexcept
{
static
constexpr
auto
impl
()
noexcept
{
constexpr
std
::
size_t
len
=
(
Strs
.
size
()
+
...
+
0
);
std
::
array
<
char
,
len
+
1
>
arr
{};
auto
append
=
[
i
=
0
,
&
arr
](
auto
const
&
s
)
mutable
{
for
(
auto
c
:
s
)
arr
[
i
++
]
=
c
;
auto
append
=
[
i
=
0
,
&
arr
](
auto
const
&
s
)
mutable
{
for
(
auto
c
:
s
)
arr
[
i
++
]
=
c
;
};
(
append
(
Strs
),
...);
arr
[
len
]
=
0
;
...
...
@@ -948,110 +800,87 @@ struct join_s {
// Give the joined string static storage
static
constexpr
auto
arr
=
impl
();
// View as a std::string_view
static
constexpr
std
::
string_view
value
{
arr
.
data
(),
arr
.
size
()
-
1
};
static
constexpr
std
::
string_view
value
{
arr
.
data
(),
arr
.
size
()
-
1
};
};
template
<
std
::
string_view
const
&
...
Strs
>
template
<
std
::
string_view
const
&
...
Strs
>
static
constexpr
auto
join
=
join_s
<
Strs
...
>::
value
;
}
// namespace meta
/* Object model */
struct
object
{
template
<
typename
T
,
typename
O
>
friend
struct
instance
;
template
<
typename
T
,
typename
O
>
friend
struct
instance
;
template
<
typename
B
,
typename
T
>
friend
struct
classtype
;
template
<
typename
B
,
typename
T
>
friend
struct
classtype
;
template
<
typename
M
>
friend
struct
moduletype
;
template
<
typename
M
>
friend
struct
moduletype
;
private:
static
constexpr
std
::
string_view
object_of_
=
"object of "
;
static
constexpr
std
::
string_view
class_
=
"class "
;
static
constexpr
std
::
string_view
module_
=
"module "
;
private:
static
constexpr
std
::
string_view
object_of_
=
"object of "
;
static
constexpr
std
::
string_view
class_
=
"class "
;
static
constexpr
std
::
string_view
module_
=
"module "
;
};
template
<
typename
T
,
typename
O
>
struct
instance
:
T
{
template
<
typename
T
,
typename
O
>
struct
instance
:
T
{
using
type
=
T
;
static
constexpr
std
::
string_view
repr
=
meta
::
join
<
object
::
object_of_
,
T
::
repr
>
;
const
O
*
operator
->
()
const
{
return
static_cast
<
const
O
*>
(
this
);
}
O
*
operator
->
()
{
return
static_cast
<
O
*>
(
this
);
}
static
constexpr
std
::
string_view
repr
=
meta
::
join
<
object
::
object_of_
,
T
::
repr
>
;
const
O
*
operator
->
()
const
{
return
static_cast
<
const
O
*>
(
this
);
}
O
*
operator
->
()
{
return
static_cast
<
O
*>
(
this
);
}
};
template
<
typename
T
,
typename
O
>
struct
value
:
instance
<
T
,
O
>
{};
template
<
typename
T
,
typename
O
>
struct
value
:
instance
<
T
,
O
>
{};
template
<
typename
B
,
typename
T
>
struct
classtype
:
B
{
template
<
typename
B
,
typename
T
>
struct
classtype
:
B
{
using
base
=
B
;
using
type
=
T
;
static
constexpr
std
::
string_view
repr
=
meta
::
join
<
object
::
class_
,
T
::
name
>
;
const
T
*
operator
->
()
const
{
return
static_cast
<
const
T
*>
(
this
);
}
T
*
operator
->
()
{
return
static_cast
<
T
*>
(
this
);
}
const
T
*
operator
->
()
const
{
return
static_cast
<
const
T
*>
(
this
);
}
T
*
operator
->
()
{
return
static_cast
<
T
*>
(
this
);
}
};
namespace
meta
{
/* Class rebasing */
template
<
typename
T
>
struct
rebase_s
{
template
<
typename
T
>
struct
rebase_s
{
static_assert
(
always_false
<
T
>
,
"Cannot rebase this type"
);
};
template
<
template
<
typename
>
typename
Class
,
typename
Base
>
struct
rebase_s
<
Class
<
Base
>>
{
template
<
typename
Rebase
>
using
type
=
Class
<
Rebase
>
;
template
<
typename
Rebase
>
using
type
=
Class
<
Rebase
>
;
};
template
<
typename
T
,
typename
Rebase
>
using
rebase
=
typename
rebase_s
<
std
::
remove_cvref_t
<
T
>>::
template
type
<
Rebase
>;
}
// namespace meta
template
<
typename
M
>
struct
moduletype
:
object
{
template
<
typename
M
>
struct
moduletype
:
object
{
using
type
=
M
;
static
constexpr
std
::
string_view
repr
=
meta
::
join
<
object
::
module_
,
M
::
name
>
;
const
M
*
operator
->
()
const
{
return
static_cast
<
const
M
*>
(
this
);
}
M
*
operator
->
()
{
return
static_cast
<
M
*>
(
this
);
}
const
M
*
operator
->
()
const
{
return
static_cast
<
const
M
*>
(
this
);
}
M
*
operator
->
()
{
return
static_cast
<
M
*>
(
this
);
}
};
struct
function
{};
struct
method
:
function
{};
struct
classmethod
:
function
{};
struct
staticmethod
:
function
{};
template
<
typename
S
,
typename
F
>
struct
boundmethod
:
object
{
template
<
typename
S
,
typename
F
>
struct
boundmethod
:
object
{
using
Self
=
S
;
using
Func
=
F
;
...
...
@@ -1059,44 +888,38 @@ struct boundmethod : object {
boundmethod
(
boundmethod
&
)
=
default
;
boundmethod
(
boundmethod
&&
)
=
default
;
boundmethod
&
operator
=
(
boundmethod
&
)
=
default
;
boundmethod
&
operator
=
(
boundmethod
&&
)
=
default
;
boundmethod
&
operator
=
(
boundmethod
&
)
=
default
;
boundmethod
&
operator
=
(
boundmethod
&&
)
=
default
;
template
<
typename
T
>
boundmethod
(
const
boundmethod
<
T
,
F
>
&
m
)
:
self
(
m
.
self
),
func
(
m
.
func
)
{}
boundmethod
(
const
boundmethod
<
T
,
F
>
&
m
)
:
self
(
m
.
self
),
func
(
m
.
func
)
{}
template
<
typename
T
>
boundmethod
(
boundmethod
<
T
,
F
>
&&
m
)
:
self
(
std
::
move
(
m
.
self
)),
func
(
m
.
func
)
{}
boundmethod
(
boundmethod
<
T
,
F
>
&&
m
)
:
self
(
std
::
move
(
m
.
self
)),
func
(
m
.
func
)
{}
template
<
typename
T
>
boundmethod
&
operator
=
(
boundmethod
<
T
,
F
>
&
m
)
{
template
<
typename
T
>
boundmethod
&
operator
=
(
boundmethod
<
T
,
F
>
&
m
)
{
func
=
m
.
func
;
self
=
m
.
self
;
return
*
this
;
}
template
<
typename
T
>
boundmethod
&
operator
=
(
boundmethod
<
T
,
F
>
&&
m
)
{
template
<
typename
T
>
boundmethod
&
operator
=
(
boundmethod
<
T
,
F
>
&&
m
)
{
func
=
std
::
move
(
m
.
func
);
self
=
std
::
move
(
m
.
self
);
return
*
this
;
}
template
<
typename
...
Args
>
auto
operator
()
(
Args
&&
...
args
)
&
{
template
<
typename
...
Args
>
auto
operator
()(
Args
&&
...
args
)
&
{
return
func
(
forward
(
self
),
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
...
Args
>
auto
operator
()
(
Args
&&
...
args
)
&&
{
template
<
typename
...
Args
>
auto
operator
()(
Args
&&
...
args
)
&&
{
return
func
(
forward
(
std
::
move
(
self
)),
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
T
,
typename
G
>
friend
struct
boundmethod
;
template
<
typename
T
,
typename
G
>
friend
struct
boundmethod
;
template
<
meta
::
instance
T
,
meta
::
method
G
>
friend
auto
bind
(
T
&&
,
const
G
&
);
template
<
meta
::
instance
T
,
meta
::
method
G
>
friend
auto
bind
(
T
&&
,
const
G
&
);
template
<
meta
::
classtype
T
,
meta
::
classmethod
G
>
friend
auto
bind
(
T
&&
,
const
G
&
);
...
...
@@ -1104,139 +927,152 @@ struct boundmethod : object {
template
<
meta
::
instance
T
,
meta
::
classmethod
G
>
friend
auto
bind
(
T
&&
,
const
G
&
);
const
F
&
_func_
()
const
{
return
func
;
}
const
F
&
_func_
()
const
{
return
func
;
}
const
S
&
_self_
()
const
{
return
self
;
}
const
S
&
_self_
()
const
{
return
self
;
}
private:
template
<
typename
T
>
boundmethod
(
T
&&
self
,
F
func
)
:
self
(
std
::
forward
<
T
>
(
self
)),
func
(
func
)
{}
private:
template
<
typename
T
>
boundmethod
(
T
&&
self
,
F
func
)
:
self
(
std
::
forward
<
T
>
(
self
)),
func
(
func
)
{}
[[
no_unique_address
]]
S
self
;
[[
no_unique_address
]]
F
func
;
[[
no_unique_address
]]
S
self
;
[[
no_unique_address
]]
F
func
;
};
namespace
meta
{
/* Specialisations for boundmethod */
template
<
boundmethod
T
>
struct
pack_s
<
T
>
{
template
<
boundmethod
T
>
struct
pack_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
pack
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
pack
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
rc_s
<
T
>
{
template
<
boundmethod
T
>
struct
rc_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
rc
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
rc
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
arc_s
<
T
>
{
template
<
boundmethod
T
>
struct
arc_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
arc
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
arc
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
box_s
<
T
>
{
template
<
boundmethod
T
>
struct
box_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
box
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
box
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
ref_s
<
T
>
{
template
<
boundmethod
T
>
struct
ref_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
ref
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
ref
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
borrow_s
<
T
>
{
template
<
boundmethod
T
>
struct
borrow_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
borrow
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
borrow
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
forward_s
<
T
>
{
template
<
boundmethod
T
>
struct
forward_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
forward
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
forward
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
forward_s
<
T
&&>
{
template
<
boundmethod
T
>
struct
forward_s
<
T
&&>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
forward
<
typename
U
::
Self
&&>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
forward
<
typename
U
::
Self
&&>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
recover_s
<
T
>
{
template
<
boundmethod
T
>
struct
recover_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
recover
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
recover
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
template
<
boundmethod
T
>
struct
own_s
<
T
>
{
template
<
boundmethod
T
>
struct
own_s
<
T
>
{
using
U
=
std
::
remove_cvref_t
<
T
>
;
using
type
=
referencemodel
::
boundmethod
<
own
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
using
type
=
referencemodel
::
boundmethod
<
own
<
typename
U
::
Self
>
,
typename
U
::
Func
>
;
};
}
// namespace meta
/* Attribute access with on-the-fly method binding */
template
<
meta
::
instance
S
,
meta
::
method
F
>
auto
bind
(
S
&&
self
,
const
F
&
func
)
{
template
<
meta
::
instance
S
,
meta
::
method
F
>
auto
bind
(
S
&&
self
,
const
F
&
func
)
{
return
boundmethod
<
meta
::
forward
<
S
&&>
,
F
>
(
std
::
forward
<
S
>
(
self
),
func
);
}
template
<
meta
::
classtype
S
,
meta
::
classmethod
F
>
auto
bind
(
S
&&
self
,
const
F
&
func
)
{
return
boundmethod
<
std
::
remove_cvref_t
<
S
>
,
F
>
{
self
,
func
};
auto
bind
(
S
&&
self
,
const
F
&
func
)
{
return
boundmethod
<
std
::
remove_cvref_t
<
S
>
,
F
>
{
self
,
func
};
}
template
<
meta
::
instance
S
,
meta
::
classmethod
F
>
auto
bind
(
S
&&
,
const
F
&
func
)
{
auto
bind
(
S
&&
,
const
F
&
func
)
{
using
type
=
typename
meta
::
unwrap_all
<
S
>::
type
;
static_assert
(
sizeof
(
type
)
==
1
);
return
boundmethod
<
type
,
F
>
{
type
{},
func
};
return
boundmethod
<
type
,
F
>
{
type
{},
func
};
}
template
<
typename
S
,
typename
A
,
typename
...
T
>
decltype
(
auto
)
bind
(
S
&&
,
const
A
&
attr
,
T
...)
{
decltype
(
auto
)
bind
(
S
&&
,
const
A
&
attr
,
T
...)
{
return
attr
;
}
#define dot(OBJ, NAME)\
[](auto &&
obj) -> decltype(auto) {
\
return referencemodel::bind(std::forward<decltype(obj)>(obj), obj->NAME);\
#define dot(OBJ, NAME)
\
[](auto &&
obj) -> decltype(auto) {
\
return referencemodel::bind(std::forward<decltype(obj)>(obj), obj->NAME);
\
}(OBJ)
/* Operators */
namespace
meta
{
// note: using dot here would cause hard failure instead of invalid constraint
/* + */
template
<
typename
Left
,
typename
Right
>
#define LR_OP(OP, DUNDER) \
namespace meta { \
template <typename Left, typename Right> \
concept Left##DUNDER##able = requires(Left left, Right right) { \
left->oo__##DUNDER##__oo(left, right); \
}; \
\
template <typename Left, typename Right> \
concept Right##DUNDER##able = requires(Left left, Right right) { \
right->oo__r##DUNDER##__oo(right, left); \
}; \
\
template <typename Left, typename Right> \
concept DUNDER##able = \
Left##DUNDER##able<Left, Right> || Right##DUNDER##able<Left, Right>; \
} \
template <meta::object Left, meta::object Right> \
requires meta::DUNDER \
##able<Left, Right> auto operator OP(Left &&left, Right &&right) { \
if constexpr (meta::Left##DUNDER##able<Left, Right>) { \
return dot(std::forward<Left>(left), \
oo__##DUNDER##__oo)(std::forward<Right>(right)); \
} else { \
if constexpr (meta::Right##DUNDER##able<Left, Right>) { \
return dot(std::forward<Right>(right), \
oo__r##DUNDER##__oo)(std::forward<Left>(left)); \
} \
} \
}
/*template <typename Left, typename Right>
concept LeftAddable = requires (Left left, Right right) {
// note: using dot here would cause hard failure instead of invalid constraint
left->oo__add__oo(left, right);
};
...
...
@@ -1247,15 +1083,13 @@ concept RightAddable = requires (Left left, Right right) {
};
template <typename Left, typename Right>
concept
Addable
=
LeftAddable
<
Left
,
Right
>
||
RightAddable
<
Left
,
Right
>
;
}
concept Addable = LeftAddable<Left, Right> || RightAddable<Left, Right>;*/
}
// namespace meta
/* + */
template
<
meta
::
object
Left
,
meta
::
object
Right
>
/*
template <meta::object Left, meta::object Right>
requires meta::Addable<Left, Right>
auto operator + (Left && left, Right && right) {
if constexpr (meta::LeftAddable<Left, Right>) {
...
...
@@ -1269,12 +1103,19 @@ auto operator + (Left && left, Right && right) {
}
}
}
*/
LR_OP
(
+
,
add
)
LR_OP
(
-
,
sub
)
LR_OP
(
*
,
mul
)
LR_OP
(
/
,
truediv
)
LR_OP
(
%
,
mod
)
LR_OP
(
<<
,
lshift
)
LR_OP
(
>>
,
rshift
)
LR_OP
(
&
,
and
)
LR_OP
(
|
,
or
)
LR_OP
(
^
,
xor
)
}
// namespace referencemodel
#endif // REFERENCEMODEL_H
typon/include/python/socket.hpp
View file @
2e7eaeb0
...
...
@@ -6,8 +6,8 @@
#define TYPON_SOCKET_HPP
#include "builtins.hpp"
#include <netinet/in.h>
#include <netdb.h>
#include <netinet/in.h>
#include <tuple>
namespace
py_socket
{
...
...
@@ -25,13 +25,15 @@ struct socket_t {
struct
socket_s
{
struct
py_type
{
METHOD
(
typon
::
Task
<
std
::
tuple
<
TyObj
<
py_type
>
COMMA
()
std
::
string
>>
,
accept
,
(
Self
self
),
{
int
connfd
=
co_await
typon
::
io
::
accept
(
self
->
fd
,
NULL
,
NULL
);
if
(
connfd
<
0
)
{
system_error
(
-
connfd
,
"accept()"
);
}
co_return
std
::
make_tuple
(
tyObj
<
py_type
>
(
connfd
),
std
::
string
(
""
));
// TODO
})
METHOD
(
typon
::
Task
<
std
::
tuple
<
TyObj
<
py_type
>
COMMA
()
std
::
string
>>
,
accept
,
(
Self
self
),
{
int
connfd
=
co_await
typon
::
io
::
accept
(
self
->
fd
,
NULL
,
NULL
);
if
(
connfd
<
0
)
{
system_error
(
-
connfd
,
"accept()"
);
}
co_return
std
::
make_tuple
(
tyObj
<
py_type
>
(
connfd
),
std
::
string
(
""
));
// TODO
})
METHOD
(
typon
::
Task
<
void
>
,
close
,
(
Self
self
),
{
co_await
typon
::
io
::
close
(
self
->
fd
);
})
...
...
@@ -43,23 +45,27 @@ struct socket_t {
}
})
METHOD
(
void
,
setsockopt
,
(
Self
self
,
int
level
,
int
optname
,
int
optval
),
{
if
(
::
setsockopt
(
self
->
fd
,
level
,
optname
,
&
optval
,
sizeof
(
int
))
<
0
)
{
system_error
(
errno
,
"setsockopt()"
);
}
})
METHOD
(
void
,
bind
,
(
Self
self
,
std
::
tuple
<
std
::
string
COMMA
()
int
>
address
),
{
auto
[
host
,
port
]
=
address
;
sockaddr_in6
addr
;
std
::
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin6_family
=
AF_INET6
;
addr
.
sin6_port
=
htons
(
port
);
addr
.
sin6_addr
=
in6addr_any
;
if
(
::
bind
(
self
->
fd
,
(
const
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
<
0
)
{
system_error
(
errno
,
"bind()"
);
}
})
METHOD
(
void
,
setsockopt
,
(
Self
self
,
int
level
,
int
optname
,
int
optval
),
{
if
(
::
setsockopt
(
self
->
fd
,
level
,
optname
,
&
optval
,
sizeof
(
int
))
<
0
)
{
system_error
(
errno
,
"setsockopt()"
);
}
})
METHOD
(
void
,
bind
,
(
Self
self
,
std
::
tuple
<
std
::
string
COMMA
()
int
>
address
),
{
auto
[
host
,
port
]
=
address
;
sockaddr_in6
addr
;
std
::
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin6_family
=
AF_INET6
;
addr
.
sin6_port
=
htons
(
port
);
addr
.
sin6_addr
=
in6addr_any
;
if
(
::
bind
(
self
->
fd
,
(
const
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
<
0
)
{
system_error
(
errno
,
"bind()"
);
}
})
METHOD
(
typon
::
Task
<
TyBytes
>
,
recv
,
(
Self
self
,
int
bufsize
),
{
TyBytes
buf
(
bufsize
,
'\0'
);
...
...
@@ -77,8 +83,7 @@ struct socket_t {
py_type
(
int
fd
=
-
1
)
:
fd
(
fd
)
{}
py_type
(
const
py_type
&
other
)
:
fd
(
other
.
fd
)
{}
py_type
(
const
py_type
&
other
)
:
fd
(
other
.
fd
)
{}
int
fd
;
};
...
...
@@ -92,21 +97,26 @@ struct socket_t {
}
}
socket
;
FUNCTION
(
auto
,
getaddrinfo
,
(
std
::
string
host
,
int
port
,
int
family
=
0
,
int
type_
=
0
,
int
proto
=
0
,
int
flags
=
0
),
{
addrinfo
hints
;
std
::
memset
(
&
hints
,
0
,
sizeof
(
hints
));
hints
.
ai_family
=
family
;
hints
.
ai_socktype
=
type_
;
hints
.
ai_protocol
=
proto
;
hints
.
ai_flags
=
flags
;
addrinfo
*
res
;
// convert port to string
std
::
string
port_str
=
std
::
to_string
(
port
);
if
(
int
err
=
::
getaddrinfo
(
host
.
c_str
(),
port_str
.
c_str
(),
&
hints
,
&
res
);
err
!=
0
)
{
system_error
(
err
,
"getaddrinfo()"
);
}
return
res
;
})
FUNCTION
(
auto
,
getaddrinfo
,
(
std
::
string
host
,
int
port
,
int
family
=
0
,
int
type_
=
0
,
int
proto
=
0
,
int
flags
=
0
),
{
addrinfo
hints
;
std
::
memset
(
&
hints
,
0
,
sizeof
(
hints
));
hints
.
ai_family
=
family
;
hints
.
ai_socktype
=
type_
;
hints
.
ai_protocol
=
proto
;
hints
.
ai_flags
=
flags
;
addrinfo
*
res
;
// convert port to string
std
::
string
port_str
=
std
::
to_string
(
port
);
if
(
int
err
=
::
getaddrinfo
(
host
.
c_str
(),
port_str
.
c_str
(),
&
hints
,
&
res
);
err
!=
0
)
{
system_error
(
err
,
"getaddrinfo()"
);
}
return
res
;
})
}
all
;
auto
&
get_all
()
{
return
all
;
}
...
...
typon/include/python/sys.hpp
View file @
2e7eaeb0
...
...
@@ -5,24 +5,20 @@
#ifndef TYPON_SYS_HPP
#define TYPON_SYS_HPP
#include <iostream>
#include "builtins.hpp"
#include <iostream>
namespace
py_sys
{
struct
sys_t
{
static
constexpr
auto
&
stdin
=
std
::
cin
;
static
constexpr
auto
&
stdout
=
std
::
cout
;
static
constexpr
auto
&
stderr
=
std
::
cerr
;
typon
::
TyList
<
TyStr
>
argv
;
typon
::
TyList
__oo
<>::
Obj
<
typon
::
TyStr__oo
<>::
Obj
>
argv
;
FUNCTION
(
void
,
exit
,
(
int
code
),
{
std
::
exit
(
code
);
})
FUNCTION
(
void
,
exit
,
(
int
code
),
{
std
::
exit
(
code
);
})
}
all
;
auto
&
get_all
()
{
return
all
;
}
auto
&
get_all
()
{
return
all
;
}
}
// namespace py_sys
#endif // TYPON_SYS_HPP
typon/trans/tests/builtins_test.py
View file @
2e7eaeb0
...
...
@@ -42,15 +42,19 @@ if __name__ == "__main__":
sum
=
0
for
i
in
range
(
15
):
sum
=
sum
+
i
a
=
[
n
for
n
in
range
(
10
)]
#b = [x for x in a if x % 2 == 0]
#
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"
,
"res="
,
5
,
"."
,
True
,
[
4
,
5
,
6
],
{
7
,
8
,
9
},
#[1, 2] + [3, 4], [5, 6] * 3, {1: 7, 9: 3},
#0x55 & 7 == 5,
#3j,
"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
,
a
)
# # a,
# # b
)
print
(
"Typon"
)
print
()
typon/trans/tests/webserver.py
View file @
2e7eaeb0
...
...
@@ -6,17 +6,12 @@ from socket import socket, SOCK_STREAM, AF_INET6, SOL_SOCKET, SO_REUSEADDR
from
typon
import
fork
#fork = lambda x: x()
BACKLOG
=
1024
PORT
=
8000
response_fmt
=
\
"HTTP/1.0 200 OK
\
r
\
n
"
\
"Content-type: text/plain
\
r
\
n
"
\
"Content-length: {}
\
r
\
n
"
\
"
\
r
\
n
"
\
"{}"
def
create_listening_socket
(
port
):
BACKLOG
=
1024
sockfd
=
socket
(
AF_INET6
,
SOCK_STREAM
)
sockfd
.
setsockopt
(
SOL_SOCKET
,
SO_REUSEADDR
,
1
)
sockfd
.
bind
((
""
,
port
))
...
...
@@ -33,6 +28,12 @@ def handle_connection(connfd, filepath):
buf
=
connfd
.
recv
(
1024
).
decode
(
"utf-8"
)
length
=
buf
.
find
(
"
\
r
\
n
\
r
\
n
"
)
content
=
read_file
(
filepath
)
response_fmt
=
\
"HTTP/1.0 200 OK
\
r
\
n
"
\
"Content-type: text/plain
\
r
\
n
"
\
"Content-length: {}
\
r
\
n
"
\
"
\
r
\
n
"
\
"{}"
response
=
response_fmt
.
format
(
len
(
content
),
content
)
connfd
.
send
(
response
.
encode
(
"utf-8"
))
connfd
.
close
()
...
...
@@ -44,6 +45,8 @@ def server_loop(sockfd, filepath):
fork
(
lambda
:
handle_connection
(
connfd
,
filepath
))
if
__name__
==
"__main__"
:
PORT
=
8000
if
len
(
sys
.
argv
)
>
2
:
print
(
"Usage: webserver [ filepath ]"
)
sys
.
exit
(
1
)
...
...
typon/trans/transpiler/phases/desugar_compare/__init__.py
View file @
2e7eaeb0
...
...
@@ -33,7 +33,8 @@ class DesugarCompare(ast.NodeTransformer):
)
if
type
(
op
)
in
(
ast
.
NotIn
,
ast
.
IsNot
):
call
=
ast
.
UnaryOp
(
ast
.
Not
(),
call
,
**
lnd
)
call
.
orig_node
=
ast
.
Compare
(
left
,
[
op
],
[
right
],
**
lnd
)
res
.
values
.
append
(
call
)
if
len
(
res
.
values
)
==
1
:
re
turn
res
.
values
[
0
]
re
s
=
res
.
values
[
0
]
return
res
\ No newline at end of file
typon/trans/transpiler/phases/emit_cpp/expr.py
View file @
2e7eaeb0
...
...
@@ -57,7 +57,7 @@ class ExpressionVisitor(NodeVisitor):
# TODO: escape sequences
yield
f"
\
"
{
repr
(
node
.
value
)[
1
:
-
1
]
}\
"
_ps"
elif
isinstance
(
node
.
value
,
bool
):
yield
str
(
node
.
value
).
lower
()
yield
f"typon::TyBool(
{
str
(
node
.
value
).
lower
()
}
)"
elif
isinstance
(
node
.
value
,
int
):
# TODO: bigints
yield
str
(
node
.
value
)
+
"_pi"
...
...
@@ -189,7 +189,7 @@ class ExpressionVisitor(NodeVisitor):
yield
from
self
.
visit
(
node
.
type
.
deref
().
return_type
)
yield
"{"
yield
"return"
yield
from
self
.
reset
().
visit
(
node
.
body
)
yield
from
self
.
visit
(
node
.
body
)
yield
";"
yield
"}"
...
...
@@ -239,9 +239,9 @@ class ExpressionVisitor(NodeVisitor):
def
visit_List
(
self
,
node
:
ast
.
List
)
->
Iterable
[
str
]:
if
node
.
elts
:
yield
"typon::TyList{"
yield
"typon::TyList
(
{"
yield
from
join
(
", "
,
map
(
self
.
visit
,
node
.
elts
))
yield
"}"
yield
"}
)
"
else
:
yield
from
self
.
visit
(
node
.
type
)
yield
"{}"
...
...
@@ -264,21 +264,24 @@ class ExpressionVisitor(NodeVisitor):
yield
"}"
if
node
.
keys
:
yield
from
self
.
visit
(
node
.
type
)
#yield from self.visit(node.type)
yield
"typon::TyDict("
yield
"{"
yield
from
join
(
", "
,
map
(
visit_item
,
node
.
keys
,
node
.
values
))
yield
"}"
yield
")"
else
:
yield
from
self
.
visit
(
node
.
type
)
yield
"{}"
def
visit_Subscript
(
self
,
node
:
ast
.
Subscript
)
->
Iterable
[
str
]:
if
isinstance
(
node
.
type
,
TypeType
)
and
isinstance
(
node
.
type
.
type_object
,
MonomorphizedUserType
):
yield
node
.
type
.
type_object
.
name
return
yield
from
self
.
prec
(
"[]"
).
visit
(
node
.
value
)
yield
"["
yield
from
self
.
reset
().
visit
(
node
.
slice
)
# if isinstance(node.type, TypeType) and isinstance(node.type.type_object, MonomorphizedUserType):
# yield node.type.type_object.name
# return
yield
"("
yield
from
self
.
visit
(
node
.
value
)
yield
")["
yield
from
self
.
visit
(
node
.
slice
)
yield
"]"
def
visit_UnaryOp
(
self
,
node
:
ast
.
UnaryOp
)
->
Iterable
[
str
]:
...
...
typon/trans/transpiler/phases/emit_cpp/function.py
View file @
2e7eaeb0
...
...
@@ -5,7 +5,7 @@ from typing import Iterable, Optional
from
transpiler.phases.emit_cpp.expr
import
ExpressionVisitor
from
transpiler.phases.typing.common
import
IsDeclare
from
transpiler.phases.typing.scope
import
Scope
from
transpiler.phases.emit_cpp.visitors
import
NodeVisitor
,
flatmap
,
CoroutineMode
from
transpiler.phases.emit_cpp.visitors
import
NodeVisitor
,
flatmap
,
CoroutineMode
,
join
from
transpiler.phases.typing.types
import
CallableInstanceType
,
BaseType
...
...
@@ -13,11 +13,15 @@ def emit_function(name: str, func: CallableInstanceType) -> Iterable[str]:
yield
f"struct : referencemodel::function {{"
yield
"typon::Task<typon::TyNone> operator()("
for
arg
,
ty
in
zip
(
func
.
block_data
.
node
.
args
.
args
,
func
.
parameters
):
yield
"auto "
yield
arg
def
emit_arg
(
arg
,
ty
):
yield
"auto"
yield
arg
.
arg
yield
from
join
(
","
,
(
emit_arg
(
arg
,
ty
)
for
arg
,
ty
in
zip
(
func
.
block_data
.
node
.
args
.
args
,
func
.
parameters
)))
yield
") const {"
for
rd
in
func
.
block_data
.
scope
.
root_decls
:
pass
yield
from
BlockVisitor
(
func
.
block_data
.
scope
,
generator
=
CoroutineMode
.
TASK
).
visit
(
func
.
block_data
.
node
.
body
)
yield
"co_return {};"
yield
"}"
...
...
@@ -152,14 +156,15 @@ class BlockVisitor(NodeVisitor):
#
# yield "}"
#
def
visit_lvalue
(
self
,
lvalue
:
ast
.
expr
,
declare
:
IsDeclare
)
->
Iterable
[
str
]:
def
visit_lvalue
(
self
,
lvalue
:
ast
.
expr
,
declare
:
IsDeclare
,
allow_auto
:
bool
=
False
)
->
Iterable
[
str
]:
if
isinstance
(
lvalue
,
ast
.
Tuple
):
raise
NotImplementedError
()
# for name, decl, ty in zip(lvalue.elts, declare, lvalue.type.args):
# if decl:
# yield from self.visit_lvalue(name, True)
# yield ";"
# yield f"std::tie({', '.join(flatmap(self.visit_lvalue, lvalue.elts))})"
def
helper
(
args
):
return
self
.
visit_lvalue
(
*
args
)
yield
f"std::tie(
{
', '
.
join
(
flatmap
(
helper
,
zip
(
lvalue
.
elts
,
declare
.
detail
)))
}
)"
elif
isinstance
(
lvalue
,
ast
.
Name
):
if
lvalue
.
id
==
"_"
:
if
not
declare
:
...
...
@@ -171,9 +176,12 @@ class BlockVisitor(NodeVisitor):
# yield self.scope.declare(name, (" ".join(self.expr().visit(val)), val) if val else None,
# getattr(val, "is_future", False))
if
declare
:
yield
"decltype("
yield
from
self
.
expr
().
visit
(
declare
.
initial_value
)
yield
")"
if
allow_auto
:
yield
"auto"
else
:
yield
"decltype("
yield
from
self
.
expr
().
visit
(
declare
.
initial_value
)
yield
")"
#yield from self.visit(lvalue.type)
yield
name
elif
isinstance
(
lvalue
,
ast
.
Subscript
):
...
...
@@ -186,18 +194,30 @@ class BlockVisitor(NodeVisitor):
def
visit_Assign
(
self
,
node
:
ast
.
Assign
)
->
Iterable
[
str
]:
if
len
(
node
.
targets
)
!=
1
:
raise
NotImplementedError
(
node
)
yield
from
self
.
visit_lvalue
(
node
.
targets
[
0
],
node
.
is_declare
)
yield
from
self
.
visit_lvalue
(
node
.
targets
[
0
],
node
.
is_declare
,
True
)
yield
" = "
yield
from
self
.
expr
().
visit
(
node
.
value
)
yield
";"
def
visit_AnnAssign
(
self
,
node
:
ast
.
AnnAssign
)
->
Iterable
[
str
]:
yield
from
self
.
visit_lvalue
(
node
.
target
,
node
.
is_declare
)
yield
from
self
.
visit_lvalue
(
node
.
target
,
node
.
is_declare
,
node
.
value
is
not
None
)
if
node
.
value
:
yield
" = "
yield
from
self
.
expr
().
visit
(
node
.
value
)
yield
";"
def
visit_If
(
self
,
node
:
ast
.
If
)
->
Iterable
[
str
]:
yield
"if ("
yield
from
self
.
expr
().
visit
(
node
.
test
)
yield
")"
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
)
def
visit_For
(
self
,
node
:
ast
.
For
)
->
Iterable
[
str
]:
if
not
isinstance
(
node
.
target
,
ast
.
Name
):
...
...
@@ -216,8 +236,35 @@ class BlockVisitor(NodeVisitor):
yield
")"
yield
from
self
.
emit_block
(
node
.
inner_scope
,
node
.
orelse
)
def
visit_While
(
self
,
node
:
ast
.
While
)
->
Iterable
[
str
]:
if
node
.
orelse
:
yield
"auto"
yield
node
.
orelse_variable
yield
"= true;"
yield
"while ("
yield
from
self
.
expr
().
visit
(
node
.
test
)
yield
")"
yield
from
self
.
emit_block
(
node
.
inner_scope
,
node
.
body
)
if
node
.
orelse
:
yield
"if ("
yield
node
.
orelse_variable
yield
")"
yield
from
self
.
emit_block
(
node
.
inner_scope
,
node
.
orelse
)
def
emit_block
(
self
,
scope
:
Scope
,
items
:
Iterable
[
ast
.
stmt
])
->
Iterable
[
str
]:
yield
"{"
for
child
in
items
:
yield
from
BlockVisitor
(
scope
,
generator
=
self
.
generator
).
visit
(
child
)
yield
"}"
def
visit_Return
(
self
,
node
:
ast
.
Return
)
->
Iterable
[
str
]:
if
CoroutineMode
.
ASYNC
in
self
.
generator
:
yield
"co_return "
else
:
yield
"return "
if
node
.
value
:
yield
from
self
.
expr
().
visit
(
node
.
value
)
yield
";"
typon/trans/transpiler/phases/emit_cpp/module.py
View file @
2e7eaeb0
...
...
@@ -3,7 +3,7 @@ from typing import Iterable
from
transpiler.phases.emit_cpp.class_
import
emit_class
from
transpiler.phases.emit_cpp.function
import
emit_function
from
transpiler.phases.typing.modules
import
ModuleType
from
transpiler.phases.typing.types
import
CallableInstanceType
,
ClassTypeType
from
transpiler.phases.typing.types
import
CallableInstanceType
,
ClassTypeType
,
TypeVariable
def
emit_module
(
mod
:
ModuleType
)
->
Iterable
[
str
]:
...
...
@@ -17,6 +17,8 @@ def emit_module(mod: ModuleType) -> Iterable[str]:
if
not
field
.
in_class_def
:
continue
ty
=
field
.
type
.
deref
()
from
transpiler.phases.typing.expr
import
ScoperExprVisitor
ScoperExprVisitor
(
ty
.
block_data
.
scope
).
visit_function_call
(
ty
,
[
TypeVariable
()
for
_
in
ty
.
parameters
])
x
=
5
match
ty
:
case
CallableInstanceType
():
...
...
typon/trans/transpiler/phases/emit_cpp/visitors.py
View file @
2e7eaeb0
...
...
@@ -69,7 +69,9 @@ class NodeVisitor(UniversalVisitor):
case
types
.
TY_STR
:
yield
"typon::TyStr"
case
types
.
TypeVariable
(
name
):
raise
UnresolvedTypeVariableError
(
node
)
yield
f"$VAR__
{
name
}
"
#raise UnresolvedTypeVariableError(node)
case
types
.
GenericInstanceType
():
yield
from
self
.
visit
(
node
.
generic_parent
)
yield
"<"
...
...
typon/trans/transpiler/phases/emit_cpp2/consts.py
View file @
2e7eaeb0
...
...
@@ -72,9 +72,9 @@ PRECEDENCE_LEVELS = {op: i for i, ops in enumerate(PRECEDENCE) for op in ops}
"""Mapping of C++ operators to their precedence level."""
MAPPINGS
=
{
"True"
:
"t
rue
"
,
"False"
:
"
false
"
,
"None"
:
"
nullptr
"
,
"True"
:
"t
ypon::TyBool(true)
"
,
"False"
:
"
typon::TyBool(false)
"
,
"None"
:
"
typon::TyNone{}
"
,
"operator"
:
"operator_"
,
}
"""Mapping of Python builtin constants to C++ equivalents."""
typon/trans/transpiler/phases/typing/__init__.py
View file @
2e7eaeb0
from
transpiler.phases.typing.common
import
PRELUDE
from
transpiler.phases.typing.scope
import
VarKind
,
VarDecl
from
transpiler.phases.typing.types
import
TY_TASK
,
TY_CALLABLE
,
TY_OPTIONAL
,
TY_CPP_TYPE
,
TY_BUILTIN_FEATURE
,
TY_TUPLE
,
\
TY_DICT
,
TY_SET
,
TY_LIST
,
TY_COMPLEX
,
TY_BYTES
,
TY_STR
,
TY_FLOAT
,
TY_INT
,
TY_BOOL
,
TY_OBJECT
TY_DICT
,
TY_SET
,
TY_LIST
,
TY_COMPLEX
,
TY_BYTES
,
TY_STR
,
TY_FLOAT
,
TY_INT
,
TY_BOOL
,
TY_OBJECT
,
TY_JOIN
,
TY_FUTURE
,
\
TY_FORKED
,
TY_GENERATOR
prelude_vars
=
{
"object"
:
TY_OBJECT
,
...
...
@@ -17,7 +18,11 @@ prelude_vars = {
"tuple"
:
TY_TUPLE
,
"BuiltinFeature"
:
TY_BUILTIN_FEATURE
,
"CppType"
:
TY_CPP_TYPE
,
"Task"
:
TY_TASK
"Task"
:
TY_TASK
,
"Join"
:
TY_JOIN
,
"Future"
:
TY_FUTURE
,
"Forked"
:
TY_FORKED
,
"Generator"
:
TY_GENERATOR
,
}
PRELUDE
.
vars
.
update
({
name
:
VarDecl
(
VarKind
.
LOCAL
,
ty
.
type_type
())
for
name
,
ty
in
prelude_vars
.
items
()})
...
...
typon/trans/transpiler/phases/typing/block.py
View file @
2e7eaeb0
...
...
@@ -5,7 +5,8 @@ import importlib
from
dataclasses
import
dataclass
from
transpiler.exceptions
import
CompileError
from
transpiler.phases.typing.types
import
BaseType
,
TypeVariable
from
transpiler.phases.typing.types
import
BaseType
,
TypeVariable
,
CallableInstanceType
,
TY_NONE
,
PromiseInstanceType
,
\
TupleInstanceType
,
RuntimeValue
,
PromiseKind
from
transpiler.utils
import
highlight
,
linenodata
from
transpiler.phases.typing.common
import
ScoperVisitor
,
is_builtin
,
DeclareInfo
from
transpiler.phases.typing.expr
import
ScoperExprVisitor
,
DUNDER
...
...
@@ -80,8 +81,8 @@ class ScoperBlockVisitor(ScoperVisitor):
raise
NotImplementedError
(
node
)
target
=
node
.
targets
[
0
]
ty
=
self
.
get_type
(
node
.
value
)
decl
=
self
.
visit_assign_target
(
target
,
ty
)
node
.
is_declare
=
DeclareInfo
(
node
.
value
)
if
decl
else
None
decl
=
self
.
visit_assign_target
(
target
,
ty
,
node
.
value
)
node
.
is_declare
=
DeclareInfo
(
decl
,
node
.
value
)
if
decl
else
None
def
visit_AnnAssign
(
self
,
node
:
ast
.
AnnAssign
):
if
node
.
simple
!=
1
:
...
...
@@ -89,14 +90,14 @@ class ScoperBlockVisitor(ScoperVisitor):
if
not
isinstance
(
node
.
target
,
ast
.
Name
):
raise
NotImplementedError
(
node
)
ty
=
self
.
visit_annotation
(
node
.
annotation
)
decl
=
self
.
visit_assign_target
(
node
.
target
,
ty
)
node
.
is_declare
=
DeclareInfo
(
node
.
value
)
if
decl
else
None
decl
=
self
.
visit_assign_target
(
node
.
target
,
ty
,
node
.
value
)
node
.
is_declare
=
DeclareInfo
(
decl
,
node
.
value
)
if
decl
else
None
if
node
.
value
is
not
None
:
ty_val
=
self
.
get_type
(
node
.
value
)
__TB__
=
f"unifying annotation
{
highlight
(
node
.
annotation
)
}
with value
{
highlight
(
node
.
value
)
}
of type
{
highlight
(
ty_val
)
}
"
ty
.
unify
(
ty_val
)
def
visit_assign_target
(
self
,
target
,
decl_val
:
BaseType
)
->
bool
:
def
visit_assign_target
(
self
,
target
,
decl_val
:
BaseType
,
val
:
ast
.
expr
=
None
)
->
bool
:
__TB__
=
f"analyzing assignment target
{
highlight
(
target
)
}
with value
{
highlight
(
decl_val
)
}
"
if
isinstance
(
target
,
ast
.
Name
):
if
target
.
id
==
"_"
:
...
...
@@ -107,20 +108,26 @@ class ScoperBlockVisitor(ScoperVisitor):
vdecl
.
type
.
unify
(
decl_val
)
return
False
else
:
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:
# self.root_decls[target.id] = VarDecl(VarKind.OUTER_DECL, decl_val)
# return False
# return True
val
=
val
or
RuntimeValue
()
self
.
scope
.
function
.
vars
[
target
.
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
decl_val
,
val
)
if
self
.
scope
.
kind
==
ScopeKind
.
FUNCTION_INNER
:
self
.
root_decls
[
target
.
id
]
=
VarDecl
(
VarKind
.
OUTER_DECL
,
decl_val
)
self
.
scope
.
function
.
root_decls
[
target
.
id
]
=
val
return
False
return
True
elif
isinstance
(
target
,
ast
.
Tuple
):
if
not
isinstance
(
decl_val
,
TupleType
):
if
not
isinstance
(
decl_val
,
Tuple
Instance
Type
):
from
transpiler.phases.typing.exceptions
import
InvalidUnpackError
raise
InvalidUnpackError
(
decl_val
)
if
len
(
target
.
elts
)
!=
len
(
decl_val
.
arg
s
):
if
len
(
target
.
elts
)
!=
len
(
decl_val
.
field
s
):
from
transpiler.phases.typing.exceptions
import
InvalidUnpackCountError
raise
InvalidUnpackCountError
(
decl_val
,
len
(
target
.
elts
))
target
.
type
=
decl_val
decls
=
[
self
.
visit_assign_target
(
t
,
ty
)
for
t
,
ty
in
zip
(
target
.
elts
,
decl_val
.
arg
s
)]
# eager evaluated
decls
=
[
self
.
visit_assign_target
(
t
,
ty
,
ast
.
Name
(
str
(
t
)))
for
t
,
ty
in
zip
(
target
.
elts
,
decl_val
.
field
s
)]
# eager evaluated
return
decls
elif
isinstance
(
target
,
ast
.
Attribute
):
attr_type
=
self
.
expr
().
visit
(
target
)
...
...
@@ -202,9 +209,11 @@ class ScoperBlockVisitor(ScoperVisitor):
from
transpiler.phases.typing.exceptions
import
OutsideFunctionError
raise
OutsideFunctionError
()
ftype
=
fct
.
obj_type
assert
isinstance
(
ftype
,
Function
Type
)
assert
isinstance
(
ftype
,
CallableInstance
Type
)
vtype
=
self
.
expr
().
visit
(
node
.
value
)
if
node
.
value
else
TY_NONE
vtype
.
unify
(
ftype
.
return_type
.
return_type
if
isinstance
(
ftype
.
return_type
,
Promise
)
else
ftype
.
return_type
)
vtype
.
unify
(
ftype
.
return_type
.
deref
()
if
isinstance
(
ftype
.
return_type
.
resolve
(),
PromiseInstanceType
)
else
ftype
.
return_type
)
self
.
scope
.
diverges
=
True
#fct.has_return = True
...
...
typon/trans/transpiler/phases/typing/common.py
View file @
2e7eaeb0
...
...
@@ -129,6 +129,7 @@ def is_builtin(x, feature):
@
dataclass
class
DeclareInfo
:
detail
:
bool
|
list
[
bool
]
initial_value
:
Optional
[
ast
.
expr
]
=
None
...
...
typon/trans/transpiler/phases/typing/expr.py
View file @
2e7eaeb0
...
...
@@ -8,7 +8,7 @@ from transpiler.phases.typing.common import ScoperVisitor, is_builtin
from
transpiler.phases.typing.exceptions
import
ArgumentCountMismatchError
,
TypeMismatchKind
,
TypeMismatchError
from
transpiler.phases.typing.types
import
BaseType
,
TY_STR
,
TY_BOOL
,
TY_INT
,
TY_COMPLEX
,
TY_FLOAT
,
TY_NONE
,
\
ClassTypeType
,
ResolvedConcreteType
,
GenericType
,
CallableInstanceType
,
TY_LIST
,
TY_SET
,
TY_DICT
,
RuntimeValue
,
\
TypeVariable
,
TY_LAMBDA
,
TypeListType
,
MethodType
,
TY_TUPLE
TypeVariable
,
TY_LAMBDA
,
TypeListType
,
MethodType
,
TY_TUPLE
,
PromiseInstanceType
from
transpiler.phases.typing.scope
import
ScopeKind
,
VarDecl
,
VarKind
from
transpiler.utils
import
linenodata
...
...
@@ -52,7 +52,7 @@ class ScoperExprVisitor(ScoperVisitor):
return
res
def
visit_Tuple
(
self
,
node
:
ast
.
Tuple
)
->
BaseType
:
return
TY_TUPLE
.
instantiate
_
(
*
[
self
.
visit
(
e
)
for
e
in
node
.
elts
])
return
TY_TUPLE
.
instantiate
(
[
self
.
visit
(
e
)
for
e
in
node
.
elts
])
def
visit_Slice
(
self
,
node
:
ast
.
Slice
)
->
BaseType
:
for
n
in
(
"lower"
,
"upper"
,
"step"
):
...
...
@@ -112,13 +112,13 @@ class ScoperExprVisitor(ScoperVisitor):
rtype
=
self
.
visit_function_call
(
ftype
,
[
self
.
visit
(
arg
)
for
arg
in
node
.
args
])
actual
=
rtype
node
.
is_await
=
False
# if isinstance(actual, Promise) and actual.kind != PromiseKind.GENERATOR:
#
node.is_await = True
# actual = actual.return_typ
e.resolve()
#
#
if self.scope.function and isinstance(actual, Promise) and actual.kind == PromiseKind.FORKED \
#
and isinstance(fty := self.scope.function.obj_type.return_type, Promise):
#
fty.kind = PromiseKind.JOIN
if
isinstance
(
actual
,
PromiseInstanceType
):
# and actual.kind != PromiseKind.GENERATOR: TODO
node
.
is_await
=
True
actual
=
actual
.
valu
e
.
resolve
()
if
self
.
scope
.
function
and
isinstance
(
actual
,
Promise
)
and
actual
.
kind
==
PromiseKind
.
FORKED
\
and
isinstance
(
fty
:
=
self
.
scope
.
function
.
obj_type
.
return_type
,
Promise
):
fty
.
kind
=
PromiseKind
.
JOIN
return
actual
...
...
@@ -141,11 +141,17 @@ class ScoperExprVisitor(ScoperVisitor):
if
not
a
.
try_assign
(
b
):
raise
TypeMismatchError
(
a
,
b
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
if
not
ftype
.
is_native
:
pname
=
ftype
.
block_data
.
node
.
args
.
args
[
i
].
arg
ftype
.
block_data
.
scope
.
declare_local
(
pname
,
b
)
if
not
ftype
.
is_native
:
from
transpiler.phases.typing.block
import
ScoperBlockVisitor
vis
=
ScoperBlockVisitor
(
ftype
.
block_data
.
scope
)
scope
=
ftype
.
block_data
.
scope
vis
=
ScoperBlockVisitor
(
scope
)
for
stmt
in
ftype
.
block_data
.
node
.
body
:
vis
.
visit
(
stmt
)
#ftype.generic_parent.cache_instance(ftype)
return
ftype
.
return_type
.
resolve
()
# if isinstance(ftype, TypeType):# and isinstance(ftype.type_object, UserType):
# init: FunctionType = self.visit_getattr(ftype, "__init__").remove_self()
...
...
@@ -311,7 +317,7 @@ class ScoperExprVisitor(ScoperVisitor):
gen
:
ast
.
comprehension
=
node
.
generators
[
0
]
iter_type
=
self
.
get_iter
(
self
.
visit
(
gen
.
iter
))
node
.
input_item_type
=
self
.
get_next
(
iter_type
)
virt_scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION
_INNER
)
virt_scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION
)
from
transpiler.phases.typing.block
import
ScoperBlockVisitor
visitor
=
ScoperBlockVisitor
(
virt_scope
)
visitor
.
visit_assign_target
(
gen
.
target
,
node
.
input_item_type
)
...
...
typon/trans/transpiler/phases/typing/scope.py
View file @
2e7eaeb0
...
...
@@ -54,6 +54,7 @@ class Scope:
diverges
:
bool
=
False
class_
:
Optional
[
"Scope"
]
=
None
is_loop
:
Optional
[
ast
.
For
|
ast
.
While
]
=
None
root_decls
:
Dict
[
str
,
ast
.
expr
]
=
field
(
default_factory
=
dict
)
@
staticmethod
def
make_global
():
...
...
typon/trans/transpiler/phases/typing/stdlib.py
View file @
2e7eaeb0
...
...
@@ -15,7 +15,7 @@ from transpiler.phases.typing.scope import Scope, VarDecl, VarKind, ScopeKind
from
transpiler.phases.typing.types
import
BaseType
,
BuiltinGenericType
,
BuiltinType
,
create_builtin_generic_type
,
\
create_builtin_type
,
ConcreteType
,
GenericInstanceType
,
TypeListType
,
TypeTupleType
,
GenericParameter
,
\
GenericParameterKind
,
TypeVariable
,
ResolvedConcreteType
,
MemberDef
,
ClassTypeType
,
CallableInstanceType
,
\
MethodType
,
UniqueTypeMixin
,
GenericType
,
BlockData
MethodType
,
UniqueTypeMixin
,
GenericType
,
BlockData
,
TY_TASK
from
transpiler.phases.utils
import
NodeVisitorSeq
def
visit_generic_item
(
...
...
@@ -158,6 +158,8 @@ class StdlibVisitor(NodeVisitorSeq):
def
visit_FunctionDef
(
self
,
node
:
ast
.
FunctionDef
):
def
visit_nongeneric
(
scope
,
output
:
CallableInstanceType
):
scope
=
scope
.
child
(
ScopeKind
.
FUNCTION
)
scope
.
function
=
scope
scope
.
obj_type
=
output
arg_visitor
=
TypeAnnotationVisitor
(
scope
)
output
.
block_data
=
BlockData
(
node
,
scope
)
output
.
parameters
=
[
arg_visitor
.
visit
(
arg
.
annotation
)
for
arg
in
node
.
args
.
args
]
...
...
@@ -165,6 +167,8 @@ class StdlibVisitor(NodeVisitorSeq):
output
.
optional_at
=
len
(
node
.
args
.
args
)
-
len
(
node
.
args
.
defaults
)
output
.
is_variadic
=
args
.
vararg
is
not
None
output
.
is_native
=
self
.
is_native
if
not
self
.
is_native
:
output
.
return_type
=
TY_TASK
.
instantiate
([
output
.
return_type
])
@
dataclass
(
eq
=
False
,
init
=
False
)
class
InstanceType
(
CallableInstanceType
):
...
...
typon/trans/transpiler/phases/typing/types.py
View file @
2e7eaeb0
...
...
@@ -147,6 +147,11 @@ class TypeVariable(ConcreteType):
def
contains_internal
(
self
,
other
:
BaseType
)
->
bool
:
return
self
.
resolve
()
is
other
.
resolve
()
def
deref
(
self
):
if
self
.
resolved
is
None
:
return
self
return
self
.
resolved
.
deref
()
@
dataclass
(
eq
=
False
)
...
...
@@ -282,6 +287,13 @@ class GenericInstanceType(ResolvedConcreteType):
# is this correct?
return
self
==
other
or
any
(
a
.
contains
(
other
)
for
a
in
self
.
generic_args
)
class
PromiseKind
(
enum
.
Enum
):
TASK
=
0
JOIN
=
1
FUTURE
=
2
FORKED
=
3
GENERATOR
=
4
class
GenericParameterKind
(
enum
.
Enum
):
NORMAL
=
enum
.
auto
()
TUPLE
=
enum
.
auto
()
...
...
@@ -303,6 +315,7 @@ class GenericConstraint:
@
dataclass
(
eq
=
False
,
init
=
False
)
class
GenericType
(
BaseType
):
parameters
:
list
[
GenericParameter
]
instance_cache
:
dict
[
object
,
GenericInstanceType
]
=
field
(
default_factory
=
dict
,
init
=
False
)
def
constraints
(
self
,
args
:
list
[
ConcreteType
])
->
list
[
GenericConstraint
]:
return
[]
...
...
@@ -329,6 +342,11 @@ class GenericType(BaseType):
def
deref
(
self
):
return
self
.
instantiate_default
().
deref
()
def
cache_instance
(
self
,
instance
):
if
not
hasattr
(
self
,
"instance_cache"
):
self
.
instance_cache
=
{}
self
.
instance_cache
[
tuple
(
instance
.
generic_args
)]
=
instance
@
dataclass
(
eq
=
False
,
init
=
False
)
class
BuiltinGenericType
(
UniqueTypeMixin
,
GenericType
):
...
...
@@ -388,23 +406,45 @@ TY_DICT = create_builtin_generic_type("dict")
TY_TUPLE
=
create_builtin_generic_type
(
"tuple"
)
@
dataclass
(
eq
=
False
)
class
Task
InstanceType
(
GenericInstanceType
):
class
Promise
InstanceType
(
GenericInstanceType
):
value
:
ConcreteType
def
deref
(
self
):
return
self
.
value
.
deref
()
match
self
.
generic_parent
.
kind
:
case
PromiseKind
.
TASK
|
PromiseKind
.
JOIN
:
return
self
.
value
.
deref
()
case
_
:
return
self
@
dataclass
(
eq
=
False
)
class
PromiseType
(
UniqueTypeMixin
,
GenericType
):
kind
:
PromiseKind
class
TaskType
(
UniqueTypeMixin
,
GenericType
):
def
name
(
self
):
return
"Task"
match
self
.
kind
:
case
PromiseKind
.
TASK
:
return
"Task"
case
PromiseKind
.
JOIN
:
return
"Join"
case
PromiseKind
.
FUTURE
:
return
"Future"
case
PromiseKind
.
FORKED
:
return
"Forked"
case
PromiseKind
.
GENERATOR
:
return
"Generator"
def
_instantiate
(
self
,
args
:
list
[
ConcreteType
])
->
GenericInstanceType
:
assert
len
(
args
)
==
1
return
TaskInstanceType
(
args
[
0
])
return
PromiseInstanceType
(
args
[
0
])
TY_TASK
=
PromiseType
([
GenericParameter
(
"T"
)],
PromiseKind
.
TASK
)
TY_JOIN
=
PromiseType
([
GenericParameter
(
"T"
)],
PromiseKind
.
JOIN
)
TY_FUTURE
=
PromiseType
([
GenericParameter
(
"T"
)],
PromiseKind
.
FUTURE
)
TY_FORKED
=
PromiseType
([
GenericParameter
(
"T"
)],
PromiseKind
.
FORKED
)
TY_GENERATOR
=
PromiseType
([
GenericParameter
(
"T"
)],
PromiseKind
.
GENERATOR
)
TY_TASK
=
TaskType
()
TY_TUPLE
.
instantiate_
=
lambda
args
:
TupleInstanceType
(
args
)
...
...
typon/trans/transpiler/transpiler.py
View file @
2e7eaeb0
...
...
@@ -63,12 +63,15 @@ def transpile(source, name: str, path: Path):
yield
f"co_await dot(PROGRAMNS::
{
module
.
name
()
}
, main)();"
yield
"}"
yield
"int main(int argc, char* argv[]) {"
yield
"py_sys::all.argv = typon::TyList
<TyStr>(std::vector<TyStr
>(argv, argv + argc));"
yield
"py_sys::all.argv = typon::TyList
__oo<>::Obj(std::vector<typon::TyStr__oo<>::Obj
>(argv, argv + argc));"
yield
f"root().call();"
yield
"}"
yield
"#endif"
code
=
"
\
n
"
.
join
(
filter
(
None
,
main_module
()))
code
=
main_module
()
code
=
filter
(
None
,
code
)
code
=
list
(
code
)
code
=
"
\
n
"
.
join
(
code
)
return
code
...
...
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