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
6dc348c4
Commit
6dc348c4
authored
Aug 04, 2023
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add slices
parent
ec94fcf5
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
175 additions
and
48 deletions
+175
-48
rt/include/python/builtins.hpp
rt/include/python/builtins.hpp
+1
-0
rt/include/python/builtins/slice.hpp
rt/include/python/builtins/slice.hpp
+58
-0
rt/include/python/builtins/str.hpp
rt/include/python/builtins/str.hpp
+44
-0
trans/stdlib/__init__.py
trans/stdlib/__init__.py
+7
-0
trans/stdlib/socket_.py
trans/stdlib/socket_.py
+11
-2
trans/test_runner.py
trans/test_runner.py
+2
-1
trans/tests/a_a_a_errtest.py
trans/tests/a_a_a_errtest.py
+2
-3
trans/tests/a_a_check_socket_listening.py
trans/tests/a_a_check_socket_listening.py
+22
-39
trans/transpiler/phases/emit_cpp/expr.py
trans/transpiler/phases/emit_cpp/expr.py
+5
-0
trans/transpiler/phases/typing/__init__.py
trans/transpiler/phases/typing/__init__.py
+2
-1
trans/transpiler/phases/typing/annotations.py
trans/transpiler/phases/typing/annotations.py
+6
-1
trans/transpiler/phases/typing/expr.py
trans/transpiler/phases/typing/expr.py
+9
-1
trans/transpiler/phases/typing/types.py
trans/transpiler/phases/typing/types.py
+6
-0
No files found.
rt/include/python/builtins.hpp
View file @
6dc348c4
...
...
@@ -128,6 +128,7 @@ public:
#include "builtins/print.hpp"
#include "builtins/range.hpp"
#include "builtins/set.hpp"
#include "builtins/slice.hpp"
#include "builtins/str.hpp"
struct
{
...
...
rt/include/python/builtins/slice.hpp
0 → 100644
View file @
6dc348c4
//
// Created by Tom on 02/08/2023.
//
#ifndef TYPON_SLICE_HPP
#define TYPON_SLICE_HPP
#include <optional>
#include <utility>
#include <Python.h>
#include <stdint.h>
struct
PySlice
{
PySlice
()
=
default
;
PySlice
(
const
PySlice
&
)
=
default
;
PySlice
(
PySlice
&&
)
=
default
;
PySlice
&
operator
=
(
const
PySlice
&
)
=
default
;
PySlice
&
operator
=
(
PySlice
&&
)
=
default
;
PySlice
(
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"
);
}
}
std
::
optional
<
ssize_t
>
start
=
0
;
std
::
optional
<
ssize_t
>
stop
=
0
;
std
::
optional
<
ssize_t
>
step
=
1
;
struct
UnpackedSlice
{
ssize_t
start
,
stop
,
step
;
};
std
::
pair
<
ssize_t
,
UnpackedSlice
>
adjust_indices
(
ssize_t
seq_length
)
{
UnpackedSlice
res
;
if
(
this
->
step
==
std
::
nullopt
)
{
res
.
step
=
1
;
}
else
{
res
.
step
=
this
->
step
.
value
();
}
if
(
this
->
start
==
std
::
nullopt
)
{
res
.
start
=
res
.
step
<
0
?
PY_SSIZE_T_MAX
:
0
;
}
if
(
this
->
stop
==
std
::
nullopt
)
{
res
.
stop
=
res
.
step
<
0
?
PY_SSIZE_T_MIN
:
PY_SSIZE_T_MAX
;
}
std
::
cout
<<
"adjust "
<<
this
->
start
<<
' '
<<
this
->
stop
<<
' '
<<
this
->
step
<<
std
::
endl
;
auto
len
=
PySlice_AdjustIndices
(
seq_length
,
&
res
.
start
,
&
res
.
stop
,
res
.
step
);
return
{
len
,
res
};
}
};
#endif // TYPON_SLICE_HPP
rt/include/python/builtins/str.hpp
View file @
6dc348c4
...
...
@@ -12,6 +12,7 @@ using namespace std::literals;
#include "bytes.hpp"
#include "print.hpp"
#include "slice.hpp"
// #include <format>
#include <fmt/format.h>
...
...
@@ -21,6 +22,7 @@ public:
PyStr
(
const
std
::
string
&
s
)
:
std
::
string
(
s
)
{}
PyStr
(
std
::
string
&&
s
)
:
std
::
string
(
std
::
move
(
s
))
{}
constexpr
PyStr
(
const
char
*
s
,
size_t
count
)
:
std
::
string
(
s
,
count
)
{}
constexpr
PyStr
(
size_t
count
,
char
ch
)
:
std
::
string
(
count
,
ch
)
{}
template
<
typename
...
Args
>
PyStr
(
Args
&&
...
args
)
:
std
::
string
(
std
::
forward
<
Args
>
(
args
)...)
{}
...
...
@@ -36,6 +38,48 @@ public:
}
bool
startswith
(
const
std
::
string
&
s
)
const
{
return
this
->
starts_with
(
s
);
}
PyStr
operator
[](
PySlice
slice
)
const
{
auto
[
len
,
new_slice
]
=
slice
.
adjust_indices
(
this
->
size
());
PyStr
result
;
result
.
reserve
(
len
);
if
(
new_slice
.
start
<
new_slice
.
stop
)
{
if
(
new_slice
.
step
>
0
)
{
for
(
auto
i
=
new_slice
.
start
;
i
<
new_slice
.
stop
;
i
+=
new_slice
.
step
)
{
result
.
push_back
(
this
->
char_at
(
i
));
}
}
}
else
{
if
(
new_slice
.
step
<
0
)
{
for
(
auto
i
=
new_slice
.
start
;
i
>
new_slice
.
stop
;
i
+=
new_slice
.
step
)
{
result
.
push_back
(
this
->
char_at
(
i
));
}
}
}
return
result
;
}
PyStr
operator
[](
ssize_t
index
)
const
{
if
(
index
<
0
)
{
index
+=
this
->
size
();
}
return
PyStr
(
1
,
std
::
string
::
operator
[](
index
));
}
char
char_at
(
ssize_t
index
)
const
{
if
(
index
<
0
)
{
index
+=
this
->
size
();
}
return
this
->
begin
()[
index
];
}
};
inline
constexpr
PyStr
operator
""
_ps
(
const
char
*
s
,
size_t
len
)
noexcept
{
...
...
trans/stdlib/__init__.py
View file @
6dc348c4
...
...
@@ -9,11 +9,17 @@ class int:
def
__and__
(
self
,
other
:
Self
)
->
Self
:
...
def
__neg__
(
self
)
->
Self
:
...
def
__init__
(
self
,
x
:
str
)
->
None
:
...
assert
int
.
__add__
U
=
TypeVar
(
"U"
)
V
=
TypeVar
(
"V"
)
class
slice
:
pass
class
HasLen
(
Protocol
):
def
__len__
(
self
)
->
int
:
...
...
...
@@ -37,6 +43,7 @@ class str:
def
__add__
(
self
,
other
:
Self
)
->
Self
:
...
def
__mul__
(
self
,
other
:
int
)
->
Self
:
...
def
startswith
(
self
,
prefix
:
Self
)
->
bool
:
...
def
__getitem__
(
self
,
item
:
int
|
slice
)
->
Self
:
...
assert
len
(
"a"
)
...
...
trans/stdlib/socket_.py
View file @
6dc348c4
...
...
@@ -11,7 +11,10 @@ class socket:
def
setsockopt
(
self
,
level
:
int
,
option
:
int
,
value
:
int
)
->
None
:
pass
def
bind
(
self
,
address
:
tuple
[
str
,
int
])
->
None
:
def
bind
(
self
,
address
:
tuple
[
str
,
int
]
|
str
)
->
None
:
pass
def
connect
(
self
,
address
:
tuple
[
str
,
int
]
|
str
)
->
None
:
pass
def
listen
(
self
,
backlog
:
int
)
->
None
:
...
...
@@ -30,4 +33,10 @@ class socket:
pass
def
close
(
self
)
->
Task
[
None
]:
pass
\ No newline at end of file
pass
def
getaddrinfo
(
host
:
str
,
port
:
int
,
family
:
int
=
0
,
type
:
int
=
0
,
proto
:
int
=
0
,
flags
:
int
=
0
)
->
\
Task
[
list
[
tuple
[
int
,
int
,
int
,
str
,
tuple
[
str
,
int
]
|
str
]]]:
pass
AF_UNIX
:
int
\ No newline at end of file
trans/test_runner.py
View file @
6dc348c4
...
...
@@ -43,13 +43,14 @@ def run_tests():
continue
name_bin
=
path
.
with_suffix
(
''
).
as_posix
()
commands
=
[
f
"bash -c 'PYTHONPATH=stdlib python3 ./
{
path
.
as_posix
()
}
'"
,
f
'bash -c "PYTHONPATH=stdlib python3 ./
{
path
.
as_posix
()
}
"'
,
]
if
alt
:
=
environ
.
get
(
"ALT_RUNNER"
):
commands
.
append
(
alt
.
format
(
name_bin
=
name_bin
,
name_cpp_posix
=
name_cpp
.
as_posix
()))
else
:
print
(
"no ALT_RUNNER"
)
for
cmd
in
commands
:
print
(
cmd
)
if
system
(
cmd
)
!=
0
:
print
(
f"Error running command:
{
cmd
}
"
)
break
...
...
trans/tests/a_a_a_errtest.py
View file @
6dc348c4
import
sys
import
math
x
=
[
6
]
if
__name__
==
"__main__"
:
pass
\ No newline at end of file
a
=
"hello, world"
print
(
a
,
a
[::
-
1
])
\ No newline at end of file
trans/tests/a_a_check_socket_listening.py
View file @
6dc348c4
"""
def sense(self):
host = self.getConfig('host')
port = self.getConfig('port')
path = self.getConfig('pathname')
abstract = self.getConfig('abstract')
if host:
if path or abstract or not port:
self.logger.error(ADDRESS_USAGE)
return
# type of port must be int or str, unicode is not accepted.
family, _, _, _, addr = socket.getaddrinfo(host, int(port))[0]
else:
if bool(path) == bool(abstract):
self.logger.error(ADDRESS_USAGE)
return
family = socket.AF_UNIX
addr = path or '
\
0
' + abstract
s = socket.socket(family, socket.SOCK_STREAM)
try:
s.connect(addr)
except socket.error as e:
self.logger.error('%s: %s', type(e).__name__, e)
else:
self.logger.info("socket connection OK %r", addr)
finally:
s.close()
"""
import
sys
# prog host port
# prog path
# prog @abstract
import
socket
if
__name__
==
"__main__"
:
pass
\ No newline at end of file
s
:
socket
.
socket
if
len
(
sys
.
argv
)
==
3
:
host
=
sys
.
argv
[
1
]
port
=
sys
.
argv
[
2
]
family
,
_
,
_
,
_
,
addr
=
socket
.
getaddrinfo
(
host
,
int
(
port
))[
0
]
s
=
socket
.
socket
(
family
,
socket
.
SOCK_STREAM
)
s
.
connect
(
addr
)
elif
len
(
sys
.
argv
)
==
2
:
path
=
sys
.
argv
[
1
]
addr
:
str
if
path
.
startswith
(
'@'
):
addr
=
'
\
0
'
+
path
[
1
:]
else
:
addr
=
path
s
=
socket
.
socket
(
socket
.
AF_UNIX
,
socket
.
SOCK_STREAM
)
s
.
connect
(
addr
)
else
:
print
(
"Usage:"
,
sys
.
argv
[
0
]
,
"host port | path | @abstract"
)
sys
.
exit
(
1
)
s
.
close
()
\ No newline at end of file
trans/transpiler/phases/emit_cpp/expr.py
View file @
6dc348c4
...
...
@@ -74,6 +74,11 @@ class ExpressionVisitor(NodeVisitor):
else
:
raise
NotImplementedError
(
node
,
type
(
node
))
def
visit_Slice
(
self
,
node
:
ast
.
Slice
)
->
Iterable
[
str
]:
yield
"PySlice("
yield
from
join
(
", "
,
(
self
.
visit
(
x
or
ast
.
Constant
(
value
=
None
))
for
x
in
(
node
.
lower
,
node
.
upper
,
node
.
step
)))
yield
")"
def
visit_Name
(
self
,
node
:
ast
.
Name
)
->
Iterable
[
str
]:
res
=
self
.
fix_name
(
node
.
id
)
if
self
.
scope
.
function
and
(
decl
:
=
self
.
scope
.
get
(
res
))
and
decl
.
type
is
self
.
scope
.
function
.
obj_type
:
...
...
trans/transpiler/phases/typing/__init__.py
View file @
6dc348c4
...
...
@@ -5,7 +5,7 @@ from transpiler.phases.typing.scope import VarKind, VarDecl, ScopeKind, Scope
from
transpiler.phases.typing.stdlib
import
PRELUDE
,
StdlibVisitor
from
transpiler.phases.typing.types
import
TY_TYPE
,
TY_INT
,
TY_STR
,
TY_BOOL
,
TY_COMPLEX
,
TY_NONE
,
FunctionType
,
\
TypeVariable
,
CppType
,
PyList
,
TypeType
,
Forked
,
Task
,
Future
,
PyIterator
,
TupleType
,
TypeOperator
,
BaseType
,
\
ModuleType
,
TY_BYTES
,
TY_FLOAT
,
PyDict
ModuleType
,
TY_BYTES
,
TY_FLOAT
,
PyDict
,
TY_SLICE
PRELUDE
.
vars
.
update
({
# "int": VarDecl(VarKind.LOCAL, TY_TYPE, TY_INT),
...
...
@@ -34,6 +34,7 @@ PRELUDE.vars.update({
"Future"
:
VarDecl
(
VarKind
.
LOCAL
,
TypeType
(
Future
)),
"Iterator"
:
VarDecl
(
VarKind
.
LOCAL
,
TypeType
(
PyIterator
)),
"tuple"
:
VarDecl
(
VarKind
.
LOCAL
,
TypeType
(
TupleType
)),
"slice"
:
VarDecl
(
VarKind
.
LOCAL
,
TypeType
(
TY_SLICE
))
})
typon_std
=
Path
(
__file__
).
parent
.
parent
.
parent
.
parent
/
"stdlib"
...
...
trans/transpiler/phases/typing/annotations.py
View file @
6dc348c4
...
...
@@ -4,7 +4,7 @@ from dataclasses import dataclass, field
from
typing
import
Optional
,
List
from
transpiler.phases.typing.scope
import
Scope
from
transpiler.phases.typing.types
import
BaseType
,
TY_NONE
,
TypeType
,
TY_SELF
,
TypeVariable
from
transpiler.phases.typing.types
import
BaseType
,
TY_NONE
,
TypeType
,
TY_SELF
,
TypeVariable
,
UnionType
from
transpiler.phases.utils
import
NodeVisitorSeq
...
...
@@ -60,3 +60,8 @@ class TypeAnnotationVisitor(NodeVisitorSeq):
res
=
left
.
members
[
node
.
attr
]
assert
isinstance
(
res
,
TypeType
)
return
res
.
type_object
def
visit_BinOp
(
self
,
node
:
ast
.
BinOp
)
->
BaseType
:
if
isinstance
(
node
.
op
,
ast
.
BitOr
):
return
UnionType
(
self
.
visit
(
node
.
left
),
self
.
visit
(
node
.
right
))
raise
NotImplementedError
(
node
.
op
)
trans/transpiler/phases/typing/expr.py
View file @
6dc348c4
...
...
@@ -6,7 +6,8 @@ from typing import List
from
transpiler.phases.typing
import
ScopeKind
,
VarDecl
,
VarKind
from
transpiler.phases.typing.common
import
ScoperVisitor
from
transpiler.phases.typing.types
import
BaseType
,
TupleType
,
TY_STR
,
TY_BOOL
,
TY_INT
,
\
TY_COMPLEX
,
TY_NONE
,
FunctionType
,
PyList
,
TypeVariable
,
PySet
,
TypeType
,
PyDict
,
Promise
,
PromiseKind
,
UserType
TY_COMPLEX
,
TY_NONE
,
FunctionType
,
PyList
,
TypeVariable
,
PySet
,
TypeType
,
PyDict
,
Promise
,
PromiseKind
,
UserType
,
\
TY_SLICE
DUNDER
=
{
ast
.
Eq
:
"eq"
,
...
...
@@ -45,6 +46,13 @@ class ScoperExprVisitor(ScoperVisitor):
def
visit_Tuple
(
self
,
node
:
ast
.
Tuple
)
->
BaseType
:
return
TupleType
(
*
[
self
.
visit
(
e
)
for
e
in
node
.
elts
])
def
visit_Slice
(
self
,
node
:
ast
.
Slice
)
->
BaseType
:
for
n
in
(
"lower"
,
"upper"
,
"step"
):
if
arg
:
=
getattr
(
node
,
n
):
self
.
visit
(
arg
).
unify
(
TY_INT
)
return
TY_SLICE
def
visit_Yield
(
self
,
node
:
ast
.
Yield
)
->
BaseType
:
ytype
=
self
.
visit
(
node
.
value
)
...
...
trans/transpiler/phases/typing/types.py
View file @
6dc348c4
...
...
@@ -334,6 +334,7 @@ TY_NONE = TypeOperator.make_type("NoneType")
TY_VARARG
=
TypeOperator
.
make_type
(
"vararg"
)
TY_SELF
=
TypeOperator
.
make_type
(
"Self"
)
TY_SELF
.
gen_sub
=
lambda
this
,
typevars
,
_
:
this
TY_SLICE
=
TypeOperator
.
make_type
(
"slice"
)
class
PyList
(
TypeOperator
):
...
...
@@ -446,3 +447,8 @@ class UserType(TypeOperator):
if
type
(
self
)
!=
type
(
other
):
from
transpiler.phases.typing.exceptions
import
TypeMismatchError
,
TypeMismatchKind
raise
TypeMismatchError
(
self
,
other
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
class
UnionType
(
TypeOperator
):
def
__init__
(
self
,
*
args
:
List
[
BaseType
]):
super
().
__init__
(
args
,
"Union"
)
self
.
parents
.
extend
(
args
)
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment