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
95b8479f
Commit
95b8479f
authored
Feb 07, 2024
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Few things work
parent
ef37573d
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
437 additions
and
326 deletions
+437
-326
typon/trans/stdlib/__init__.py
typon/trans/stdlib/__init__.py
+0
-175
typon/trans/stdlib/builtins_.py
typon/trans/stdlib/builtins_.py
+175
-0
typon/trans/stdlib/typing_.py
typon/trans/stdlib/typing_.py
+4
-0
typon/trans/transpiler/__init__.py
typon/trans/transpiler/__init__.py
+11
-4
typon/trans/transpiler/phases/typing/__init__.py
typon/trans/transpiler/phases/typing/__init__.py
+4
-75
typon/trans/transpiler/phases/typing/annotations.py
typon/trans/transpiler/phases/typing/annotations.py
+0
-2
typon/trans/transpiler/phases/typing/common.py
typon/trans/transpiler/phases/typing/common.py
+2
-2
typon/trans/transpiler/phases/typing/exceptions.py
typon/trans/transpiler/phases/typing/exceptions.py
+16
-1
typon/trans/transpiler/phases/typing/expr.py
typon/trans/transpiler/phases/typing/expr.py
+5
-4
typon/trans/transpiler/phases/typing/modules.py
typon/trans/transpiler/phases/typing/modules.py
+88
-0
typon/trans/transpiler/phases/typing/stdlib.py
typon/trans/transpiler/phases/typing/stdlib.py
+47
-41
typon/trans/transpiler/phases/typing/types.py
typon/trans/transpiler/phases/typing/types.py
+85
-22
No files found.
typon/trans/stdlib/__init__.py
View file @
95b8479f
from
typing
import
Self
,
Generic
,
Protocol
,
Optional
assert
5
class
object
:
def
__eq__
(
self
,
other
:
Self
)
->
bool
:
...
def
__ne__
(
self
,
other
:
Self
)
->
bool
:
...
class
int
:
def
__add__
(
self
,
other
:
Self
)
->
Self
:
...
def
__sub__
(
self
,
other
:
Self
)
->
Self
:
...
def
__mul__
(
self
,
other
:
Self
)
->
Self
:
...
def
__and__
(
self
,
other
:
Self
)
->
Self
:
...
def
__neg__
(
self
)
->
Self
:
...
def
__init__
(
self
,
x
:
object
)
->
None
:
...
def
__lt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__gt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__mod__
(
self
,
other
:
Self
)
->
Self
:
...
def
__ge__
(
self
,
other
:
Self
)
->
bool
:
...
class
float
:
def
__init__
(
self
,
x
:
object
)
->
None
:
...
assert
int
.
__add__
assert
(
5
).
__add__
class
slice
:
pass
class
HasLen
(
Protocol
):
def
__len__
(
self
)
->
int
:
...
def
len
(
x
:
HasLen
)
->
int
:
...
class
Iterator
[
U
](
Protocol
):
def
__iter__
(
self
)
->
Self
:
...
def
__next__
(
self
)
->
U
:
...
class
Iterable
[
U
](
Protocol
):
def
__iter__
(
self
)
->
Iterator
[
U
]:
...
class
str
:
def
find
(
self
,
sub
:
Self
)
->
int
:
...
def
format
(
self
,
*
args
)
->
Self
:
...
def
encode
(
self
,
encoding
:
Self
)
->
bytes
:
...
def
__len__
(
self
)
->
int
:
...
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
:
...
def
isspace
(
self
)
->
bool
:
...
def
__contains__
(
self
,
item
:
Self
)
->
bool
:
...
assert
len
(
"a"
)
class
bytes
:
def
decode
(
self
,
encoding
:
str
)
->
str
:
...
def
__len__
(
self
)
->
int
:
...
class
list
[
U
]:
def
__add__
(
self
,
other
:
Self
)
->
Self
:
...
def
__mul__
(
self
,
other
:
int
)
->
Self
:
...
def
__getitem__
(
self
,
index
:
int
)
->
U
:
...
def
__setitem__
(
self
,
index
:
int
,
value
:
U
)
->
None
:
...
def
pop
(
self
,
index
:
int
=
-
1
)
->
U
:
...
def
__iter__
(
self
)
->
Iterator
[
U
]:
...
def
__len__
(
self
)
->
int
:
...
def
append
(
self
,
value
:
U
)
->
None
:
...
def
__contains__
(
self
,
item
:
U
)
->
bool
:
...
def
__init__
(
self
,
it
:
Iterator
[
U
])
->
None
:
...
assert
[
1
,
2
].
__iter__
()
assert
list
[
int
].
__iter__
class
dict
[
U
,
V
]:
def
__getitem__
(
self
,
key
:
U
)
->
V
:
...
def
__setitem__
(
self
,
key
:
U
,
value
:
V
)
->
None
:
...
def
__len__
(
self
)
->
int
:
...
assert
(
len
([
"a"
]))
#assert list.__getitem__
assert
[].
__getitem__
assert
[
4
].
__getitem__
assert
[
1
,
2
,
3
][
1
]
def
iter
[
U
](
x
:
Iterable
[
U
])
->
Iterator
[
U
]:
...
assert
iter
def
next
[
U
](
it
:
Iterator
[
U
],
default
:
Optional
[
U
]
=
None
)
->
U
:
...
# what happens with multiple functions
assert
iter
([
"1"
,
"2"
])
def
identity
[
U
](
x
:
U
)
->
U
:
...
assert
identity
(
1
)
assert
identity
(
"a"
)
def
identity_2
[
U
,
V
](
x
:
U
,
y
:
V
)
->
tuple
[
U
,
V
]:
...
assert
list
.
__add__
assert
list
.
__add__
([
5
],
[[
6
][
0
]])
assert
list
[
int
].
__add__
assert
identity_2
(
1
,
"a"
)
assert
lambda
x
,
y
:
identity_2
(
x
,
y
)
assert
lambda
x
:
identity_2
(
x
,
x
)
def
print
(
*
args
)
->
None
:
...
assert
print
def
input
(
prompt
:
str
=
""
)
->
str
:
...
def
range
(
*
args
)
->
Iterator
[
int
]:
...
assert
[].
__add__
assert
[
6
].
__add__
assert
[
True
].
__add__
assert
lambda
x
:
[
x
].
__add__
assert
next
(
range
(
6
),
None
)
class
file
:
def
read
(
self
,
size
:
int
=
0
)
->
Task
[
str
]:
...
def
close
(
self
)
->
Task
[
None
]:
...
def
__enter__
(
self
)
->
Self
:
...
def
__exit__
(
self
)
->
Task
[
bool
]:
...
def
open
(
filename
:
str
,
mode
:
str
)
->
Task
[
file
]:
...
def
__test_opt
(
x
:
int
,
y
:
int
=
5
)
->
int
:
...
assert
__test_opt
assert
__test_opt
(
5
)
assert
__test_opt
(
5
,
6
)
assert
not
__test_opt
(
5
,
6
,
7
)
assert
not
__test_opt
()
class
__test_type
:
def
__init__
(
self
)
->
None
:
...
def
test_opt
(
self
,
x
:
int
,
y
:
int
=
5
)
->
int
:
...
assert
__test_type
().
test_opt
(
5
)
assert
__test_type
().
test_opt
(
5
,
6
)
assert
not
__test_type
().
test_opt
(
5
,
6
,
7
)
assert
not
__test_type
().
test_opt
()
def
exit
(
code
:
int
|
None
=
None
)
->
None
:
...
class
Exception
:
def
__init__
(
self
,
message
:
str
)
->
None
:
...
\ No newline at end of file
typon/trans/stdlib/builtins_.py
0 → 100644
View file @
95b8479f
from
typing
import
Self
,
Protocol
,
Optional
assert
5
class
object
:
def
__eq__
(
self
,
other
:
Self
)
->
bool
:
...
def
__ne__
(
self
,
other
:
Self
)
->
bool
:
...
class
int
:
def
__add__
(
self
,
other
:
Self
)
->
Self
:
...
def
__sub__
(
self
,
other
:
Self
)
->
Self
:
...
def
__mul__
(
self
,
other
:
Self
)
->
Self
:
...
def
__and__
(
self
,
other
:
Self
)
->
Self
:
...
def
__neg__
(
self
)
->
Self
:
...
def
__init__
(
self
,
x
:
object
)
->
None
:
...
def
__lt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__gt__
(
self
,
other
:
Self
)
->
bool
:
...
def
__mod__
(
self
,
other
:
Self
)
->
Self
:
...
def
__ge__
(
self
,
other
:
Self
)
->
bool
:
...
class
float
:
def
__init__
(
self
,
x
:
object
)
->
None
:
...
assert
int
.
__add__
assert
(
5
).
__add__
class
slice
:
pass
class
HasLen
(
Protocol
):
def
__len__
(
self
)
->
int
:
...
def
len
(
x
:
HasLen
)
->
int
:
...
class
Iterator
[
U
](
Protocol
):
def
__iter__
(
self
)
->
Self
:
...
def
__next__
(
self
)
->
U
:
...
class
Iterable
[
U
](
Protocol
):
def
__iter__
(
self
)
->
Iterator
[
U
]:
...
class
str
:
def
find
(
self
,
sub
:
Self
)
->
int
:
...
def
format
(
self
,
*
args
)
->
Self
:
...
def
encode
(
self
,
encoding
:
Self
)
->
bytes
:
...
def
__len__
(
self
)
->
int
:
...
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
:
...
def
isspace
(
self
)
->
bool
:
...
def
__contains__
(
self
,
item
:
Self
)
->
bool
:
...
assert
len
(
"a"
)
class
bytes
:
def
decode
(
self
,
encoding
:
str
)
->
str
:
...
def
__len__
(
self
)
->
int
:
...
class
list
[
U
]:
def
__add__
(
self
,
other
:
Self
)
->
Self
:
...
def
__mul__
(
self
,
other
:
int
)
->
Self
:
...
def
__getitem__
(
self
,
index
:
int
)
->
U
:
...
def
__setitem__
(
self
,
index
:
int
,
value
:
U
)
->
None
:
...
def
pop
(
self
,
index
:
int
=
-
1
)
->
U
:
...
def
__iter__
(
self
)
->
Iterator
[
U
]:
...
def
__len__
(
self
)
->
int
:
...
def
append
(
self
,
value
:
U
)
->
None
:
...
def
__contains__
(
self
,
item
:
U
)
->
bool
:
...
def
__init__
(
self
,
it
:
Iterator
[
U
])
->
None
:
...
assert
[
1
,
2
].
__iter__
()
assert
list
[
int
].
__iter__
class
dict
[
U
,
V
]:
def
__getitem__
(
self
,
key
:
U
)
->
V
:
...
def
__setitem__
(
self
,
key
:
U
,
value
:
V
)
->
None
:
...
def
__len__
(
self
)
->
int
:
...
assert
(
len
([
"a"
]))
#assert list.__getitem__
assert
[].
__getitem__
assert
[
4
].
__getitem__
assert
[
1
,
2
,
3
][
1
]
def
iter
[
U
](
x
:
Iterable
[
U
])
->
Iterator
[
U
]:
...
assert
iter
def
next
[
U
](
it
:
Iterator
[
U
],
default
:
Optional
[
U
]
=
None
)
->
U
:
...
# what happens with multiple functions
assert
iter
([
"1"
,
"2"
])
def
identity
[
U
](
x
:
U
)
->
U
:
...
assert
identity
(
1
)
assert
identity
(
"a"
)
def
identity_2
[
U
,
V
](
x
:
U
,
y
:
V
)
->
tuple
[
U
,
V
]:
...
assert
list
.
__add__
assert
list
.
__add__
([
5
],
[[
6
][
0
]])
assert
list
[
int
].
__add__
assert
identity_2
(
1
,
"a"
)
assert
lambda
x
,
y
:
identity_2
(
x
,
y
)
assert
lambda
x
:
identity_2
(
x
,
x
)
def
print
(
*
args
)
->
None
:
...
assert
print
def
input
(
prompt
:
str
=
""
)
->
str
:
...
def
range
(
*
args
)
->
Iterator
[
int
]:
...
assert
[].
__add__
assert
[
6
].
__add__
assert
[
True
].
__add__
assert
lambda
x
:
[
x
].
__add__
assert
next
(
range
(
6
),
None
)
class
file
:
def
read
(
self
,
size
:
int
=
0
)
->
Task
[
str
]:
...
def
close
(
self
)
->
Task
[
None
]:
...
def
__enter__
(
self
)
->
Self
:
...
def
__exit__
(
self
)
->
Task
[
bool
]:
...
def
open
(
filename
:
str
,
mode
:
str
)
->
Task
[
file
]:
...
def
__test_opt
(
x
:
int
,
y
:
int
=
5
)
->
int
:
...
assert
__test_opt
assert
__test_opt
(
5
)
assert
__test_opt
(
5
,
6
)
assert
not
__test_opt
(
5
,
6
,
7
)
assert
not
__test_opt
()
class
__test_type
:
def
__init__
(
self
)
->
None
:
...
def
test_opt
(
self
,
x
:
int
,
y
:
int
=
5
)
->
int
:
...
assert
__test_type
().
test_opt
(
5
)
assert
__test_type
().
test_opt
(
5
,
6
)
assert
not
__test_type
().
test_opt
(
5
,
6
,
7
)
assert
not
__test_type
().
test_opt
()
def
exit
(
code
:
int
|
None
=
None
)
->
None
:
...
class
Exception
:
def
__init__
(
self
,
message
:
str
)
->
None
:
...
\ No newline at end of file
typon/trans/stdlib/typing_.py
View file @
95b8479f
# coding: utf-8
Protocol
=
BuiltinFeature
[
"Protocol"
]
Self
=
BuiltinFeature
[
"Self"
]
Optional
=
BuiltinFeature
[
"Optional"
]
\ No newline at end of file
typon/trans/transpiler/__init__.py
View file @
95b8479f
...
...
@@ -6,12 +6,15 @@ import inspect
import
os
import
traceback
from
pathlib
import
Path
#os.environ["TERM"] = "xterm-256"
import
colorama
from
transpiler.phases.desugar_compare
import
DesugarCompare
from
transpiler.phases.desugar_op
import
DesugarOp
from
transpiler.phases.typing
import
PRELUDE
from
transpiler.phases.typing.modules
import
parse_module
colorama
.
init
()
...
...
@@ -20,10 +23,9 @@ from transpiler.phases.desugar_with import DesugarWith
#from transpiler.phases.emit_cpp.file import FileVisitor
from
transpiler.phases.if_main
import
IfMainVisitor
#from transpiler.phases.typing.block import ScoperBlockVisitor
from
transpiler.phases.typing.scope
import
Scope
from
transpiler.phases.typing.scope
import
Scope
,
ScopeKind
from
transpiler.utils
import
highlight
from
itertools
import
islice
import
sys
import
colorful
as
cf
...
...
@@ -43,7 +45,7 @@ def exception_hook(exc_type, exc_value, tb):
local_vars
=
tb
.
tb_frame
.
f_locals
name
=
tb
.
tb_frame
.
f_code
.
co_name
if
name
==
"transpile"
:
if
name
in
(
"transpile"
,
"parse_module"
)
:
last_file
=
local_vars
[
"path"
]
if
name
==
"visit"
and
(
node
:
=
local_vars
[
"node"
])
and
isinstance
(
node
,
ast
.
AST
):
...
...
@@ -66,7 +68,7 @@ def exception_hook(exc_type, exc_value, tb):
print
()
tb
=
tb
.
tb_next
if
last_node
is
not
None
:
if
last_node
is
not
None
and
last_file
is
not
None
:
print
()
if
not
hasattr
(
last_node
,
"lineno"
):
print
(
cf
.
red
(
"Error: "
),
cf
.
white
(
"No line number available"
))
...
...
@@ -175,6 +177,11 @@ else:
pydevd
.
original_excepthook
=
sys
.
excepthook
typon_std
=
Path
(
__file__
).
parent
.
parent
/
"stdlib"
#discover_module(typon_std, PRELUDE.child(ScopeKind.GLOBAL))
parse_module
(
"builtins"
,
typon_std
,
PRELUDE
)
def
transpile
(
source
,
name
:
str
,
path
=
None
):
__TB__
=
f"transpiling module
{
cf
.
white
(
name
)
}
"
res
=
ast
.
parse
(
source
,
type_comments
=
True
)
...
...
typon/trans/transpiler/phases/typing/__init__.py
View file @
95b8479f
import
ast
from
pathlib
import
Path
from
logging
import
debug
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
,
ResolvedConcreteType
,
\
MemberDef
,
TY_FLOAT
,
TY_BUILTIN_FEATURE
,
TY_TUPLE
,
TY_DICT
,
TY_SET
,
TY_LIST
,
TY_BYTES
,
TY_OBJECT
,
TY_CPP_TYPE
,
\
TY_OPTIONAL
,
UniqueTypeMixin
,
TY_CALLABLE
,
TY_TASK
# PRELUDE.vars.update({
# "int": VarDecl(VarKind.LOCAL, TypeType(TY_INT)),
# "float": VarDecl(VarKind.LOCAL, TypeType(TY_FLOAT)),
# "str": VarDecl(VarKind.LOCAL, TypeType(TY_STR)),
# "bytes": VarDecl(VarKind.LOCAL, TypeType(TY_BYTES)),
# "bool": VarDecl(VarKind.LOCAL, TypeType(TY_BOOL)),
# "complex": VarDecl(VarKind.LOCAL, TypeType(TY_COMPLEX)),
# "None": VarDecl(VarKind.LOCAL, TypeType(TY_NONE)),
# "Callable": VarDecl(VarKind.LOCAL, TypeType(FunctionType)),
# #"TypeVar": VarDecl(VarKind.LOCAL, TypeType(TypeVariable)),
# "CppType": VarDecl(VarKind.LOCAL, TypeType(CppType)),
# "list": VarDecl(VarKind.LOCAL, TypeType(PyList)),
# "dict": VarDecl(VarKind.LOCAL, TypeType(PyDict)),
# "Forked": VarDecl(VarKind.LOCAL, TypeType(Forked)),
# "Task": VarDecl(VarKind.LOCAL, TypeType(Task)),
# "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)),
# "object": VarDecl(VarKind.LOCAL, TypeType(TY_OBJECT)),
# "BuiltinFeature": VarDecl(VarKind.LOCAL, TypeType(BuiltinFeature)),
# "Any": VarDecl(VarKind.LOCAL, TypeType(TY_OBJECT)),
# "Optional": VarDecl(VarKind.LOCAL, TypeType(lambda x: UnionType(x, TY_NONE))),
# })
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
prelude_vars
=
{
"object"
:
TY_OBJECT
,
...
...
@@ -46,50 +17,8 @@ prelude_vars = {
"tuple"
:
TY_TUPLE
,
"BuiltinFeature"
:
TY_BUILTIN_FEATURE
,
"CppType"
:
TY_CPP_TYPE
,
"Optional"
:
TY_OPTIONAL
,
"Callable"
:
TY_CALLABLE
,
"Task"
:
TY_TASK
}
PRELUDE
.
vars
.
update
({
name
:
VarDecl
(
VarKind
.
LOCAL
,
ty
.
type_type
())
for
name
,
ty
in
prelude_vars
.
items
()})
typon_std
=
Path
(
__file__
).
parent
.
parent
.
parent
.
parent
/
"stdlib"
def
make_module
(
name
:
str
,
scope
:
Scope
)
->
ResolvedConcreteType
:
class
CreatedType
(
UniqueTypeMixin
,
ResolvedConcreteType
):
def
name
(
self
):
return
name
ty
=
CreatedType
()
for
n
,
v
in
scope
.
vars
.
items
():
ty
.
fields
[
n
]
=
MemberDef
(
v
.
type
,
v
.
val
,
False
)
return
ty
def
discover_module
(
path
:
Path
,
scope
):
for
child
in
sorted
(
path
.
iterdir
()):
if
child
.
is_dir
():
mod_scope
=
PRELUDE
.
child
(
ScopeKind
.
GLOBAL
)
discover_module
(
child
,
mod_scope
)
scope
.
vars
[
child
.
name
]
=
make_mod_decl
(
child
.
name
,
mod_scope
)
elif
child
.
name
==
"__init__.py"
:
StdlibVisitor
(
scope
).
visit
(
ast
.
parse
(
child
.
read_text
()))
debug
(
f"Visited
{
child
}
"
)
elif
child
.
suffix
==
".py"
:
mod_scope
=
PRELUDE
.
child
(
ScopeKind
.
GLOBAL
)
StdlibVisitor
(
mod_scope
).
visit
(
ast
.
parse
(
child
.
read_text
()))
if
child
.
stem
[
-
1
]
==
"_"
:
child
=
child
.
with_name
(
child
.
stem
[:
-
1
])
scope
.
vars
[
child
.
stem
]
=
make_mod_decl
(
child
.
name
,
mod_scope
)
debug
(
f"Visited
{
child
}
"
)
def
make_mod_decl
(
child
,
mod_scope
):
return
VarDecl
(
VarKind
.
MODULE
,
make_module
(
child
,
mod_scope
),
{
k
:
v
.
type
for
k
,
v
in
mod_scope
.
vars
.
items
()})
discover_module
(
typon_std
,
PRELUDE
)
debug
(
"Stdlib visited!"
)
#exit()
\ No newline at end of file
typon/trans/transpiler/phases/typing/annotations.py
View file @
95b8479f
...
...
@@ -43,10 +43,8 @@ class TypeAnnotationVisitor(NodeVisitorSeq):
elif
ty_op
is
TY_CPP_TYPE
:
assert
len
(
args
)
==
1
return
make_cpp_type
(
args
[
0
])
# return ty_op(*args)
assert
isinstance
(
ty_op
,
GenericType
)
return
ty_op
.
instantiate
(
args
)
# return TypeOperator([self.visit(node.value)], self.visit(node.slice.value))
def
visit_List
(
self
,
node
:
ast
.
List
)
->
BaseType
:
return
TypeListType
([
self
.
visit
(
elt
)
for
elt
in
node
.
elts
])
...
...
typon/trans/transpiler/phases/typing/common.py
View file @
95b8479f
...
...
@@ -5,7 +5,7 @@ from typing import Dict, Optional
from
transpiler.utils
import
highlight
from
transpiler.phases.typing.annotations
import
TypeAnnotationVisitor
from
transpiler.phases.typing.scope
import
Scope
,
ScopeKind
,
VarDecl
,
VarKind
from
transpiler.phases.typing.types
import
BaseType
,
TypeVariable
,
TY_NONE
from
transpiler.phases.typing.types
import
BaseType
,
TypeVariable
,
TY_NONE
,
BuiltinFeatureType
from
transpiler.phases.utils
import
NodeVisitorSeq
,
AnnotationName
PRELUDE
=
Scope
.
make_global
()
...
...
@@ -121,4 +121,4 @@ def get_next(iter_type):
return
next_type
def
is_builtin
(
x
,
feature
):
return
isinstance
(
x
,
BuiltinFeature
)
and
x
.
val
==
feature
\ No newline at end of file
return
isinstance
(
x
,
BuiltinFeatureType
)
and
x
.
feature
()
==
feature
\ No newline at end of file
typon/trans/transpiler/phases/typing/exceptions.py
View file @
95b8479f
...
...
@@ -180,9 +180,24 @@ class UnknownNameError(CompileError):
For example:
{
highlight
(
'print(abcd)'
)
}
{
highlight
(
'import foobar'
)
}
"""
@
dataclass
class
UnknownModuleError
(
CompileError
):
name
:
str
def
__str__
(
self
)
->
str
:
return
f"Unknown module:
{
highlight
(
self
.
name
)
}
"
def
detail
(
self
,
last_node
:
ast
.
AST
=
None
)
->
str
:
return
f"""
This indicates that an attempt was made to import a module that does not exist.
For example:
{
highlight
(
'import abcd'
)
}
"""
@
dataclass
class
UnknownModuleMemberError
(
CompileError
):
...
...
typon/trans/transpiler/phases/typing/expr.py
View file @
95b8479f
...
...
@@ -4,12 +4,12 @@ import inspect
from
itertools
import
zip_longest
from
typing
import
List
from
transpiler.phases.typing
import
ScopeKind
,
VarDecl
,
VarKind
from
transpiler.phases.typing.common
import
ScoperVisitor
,
get_iter
,
get_next
,
is_builtin
from
transpiler.phases.typing.exceptions
import
ArgumentCountMismatchError
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
from
transpiler.phases.typing.scope
import
ScopeKind
,
VarDecl
,
VarKind
from
transpiler.utils
import
linenodata
DUNDER
=
{
...
...
@@ -138,7 +138,8 @@ class ScoperExprVisitor(ScoperVisitor):
raise
ArgumentCountMismatchError
(
ftype
,
arguments
)
if
a
is
None
and
ftype
.
is_variadic
:
break
assert
a
.
try_assign
(
b
)
if
not
a
.
try_assign
(
b
):
raise
TypeMismatchError
(
a
,
b
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
return
ftype
.
return_type
# if isinstance(ftype, TypeType):# and isinstance(ftype.type_object, UserType):
...
...
@@ -222,7 +223,7 @@ class ScoperExprVisitor(ScoperVisitor):
ty
.
python_func_used
=
True
if
isinstance
(
ty
,
MethodType
):
if
bound
and
field
.
in_class_def
and
type
(
field
.
val
)
!=
RuntimeValue
:
return
ty
.
remove_self
()
return
ty
.
remove_self
(
ltype
)
return
ty
...
...
typon/trans/transpiler/phases/typing/modules.py
0 → 100644
View file @
95b8479f
import
ast
from
pathlib
import
Path
from
logging
import
debug
from
transpiler.phases.typing.scope
import
Scope
,
VarKind
,
VarDecl
,
ScopeKind
from
transpiler.phases.typing.types
import
MemberDef
,
ResolvedConcreteType
,
UniqueTypeMixin
def
make_module
(
name
:
str
,
scope
:
Scope
)
->
ResolvedConcreteType
:
class
CreatedType
(
UniqueTypeMixin
,
ResolvedConcreteType
):
def
name
(
self
):
return
name
ty
=
CreatedType
()
for
n
,
v
in
scope
.
vars
.
items
():
ty
.
fields
[
n
]
=
MemberDef
(
v
.
type
,
v
.
val
,
False
)
return
ty
visited_modules
=
{}
def
parse_module
(
mod_name
:
str
,
python_path
:
Path
,
scope
=
None
):
path
=
python_path
/
mod_name
if
not
path
.
exists
():
path
=
path
.
with_suffix
(
".py"
)
if
not
path
.
exists
():
path
=
path
.
with_stem
(
mod_name
+
"_"
)
if
not
path
.
exists
():
raise
FileNotFoundError
(
f"Could not find
{
path
}
"
)
if
path
.
is_dir
():
real_path
=
path
/
"__init__.py"
else
:
real_path
=
path
if
mod
:
=
visited_modules
.
get
(
real_path
.
as_posix
()):
return
mod
from
transpiler
import
PRELUDE
mod_scope
=
scope
or
PRELUDE
.
child
(
ScopeKind
.
GLOBAL
)
if
real_path
.
suffix
==
".py"
:
from
transpiler.phases.typing.stdlib
import
StdlibVisitor
StdlibVisitor
(
python_path
,
mod_scope
).
visit
(
ast
.
parse
(
real_path
.
read_text
()))
else
:
raise
NotImplementedError
(
f"Unsupported file type
{
path
.
suffix
}
"
)
mod
=
make_mod_decl
(
mod_name
,
mod_scope
)
visited_modules
[
real_path
.
as_posix
()]
=
mod
return
mod
# def process_module(mod_path: Path, scope):
# if mod := visited_modules.get(mod_path.as_posix()):
# return mod
#
# if mod_path.is_dir():
# mod_scope = scope.child(ScopeKind.GLOBAL)
# discover_module(mod_path, mod_scope)
# mod = make_mod_decl(mod_path.name, mod_scope)
# scope.vars[mod_path.name] = mod
# elif mod_path.name == "__init__.py":
# StdlibVisitor(mod_path, scope).visit(ast.parse(mod_path.read_text()))
# mod = None
# debug(f"Visited {mod_path}")
# elif mod_path.suffix == ".py":
# mod_scope = scope.child(ScopeKind.GLOBAL)
# StdlibVisitor(mod_path, mod_scope).visit(ast.parse(mod_path.read_text()))
# if mod_path.stem[-1] == "_":
# mod_path = mod_path.with_name(mod_path.stem[:-1])
# mod = make_mod_decl(mod_path.name, mod_scope)
# scope.vars[mod_path.stem] = mod
# debug(f"Visited {mod_path}")
# return mod
#
# def discover_module(dir_path: Path, scope):
# mod = make_mod_decl(dir_path.name, scope)
# for child in sorted(dir_path.iterdir()):
# # if child.name == "__init__.py":
# # StdlibVisitor(mod_scope).visit(ast.parse(child.read_text()))
# # else:
# # process_module(child, mod_scope)
# child_mod = process_module(child, scope)
# visited_modules[child.as_posix()] = child_mod
# return mod
def
make_mod_decl
(
child
,
mod_scope
):
return
VarDecl
(
VarKind
.
LOCAL
,
make_module
(
child
,
mod_scope
),
{
k
:
v
.
type
for
k
,
v
in
mod_scope
.
vars
.
items
()})
\ No newline at end of file
typon/trans/transpiler/phases/typing/stdlib.py
View file @
95b8479f
...
...
@@ -2,9 +2,11 @@ import ast
import
dataclasses
from
abc
import
ABCMeta
from
dataclasses
import
dataclass
,
field
from
pathlib
import
Path
from
typing
import
Optional
,
List
,
Dict
,
Callable
from
logging
import
debug
from
transpiler.phases.typing.modules
import
parse_module
from
transpiler.utils
import
highlight
from
transpiler.phases.typing.annotations
import
TypeAnnotationVisitor
from
transpiler.phases.typing.common
import
PRELUDE
,
is_builtin
...
...
@@ -17,7 +19,7 @@ from transpiler.phases.typing.types import BaseType, BuiltinGenericType, Builtin
from
transpiler.phases.utils
import
NodeVisitorSeq
def
visit_generic_item
(
visit_nongeneric
:
Callable
[[
Scope
,
ConcreteType
],
None
],
visit_nongeneric
:
Callable
[[
Scope
,
Resolved
ConcreteType
],
None
],
node
,
output_type
:
BuiltinGenericType
,
scope
:
Scope
,
...
...
@@ -59,8 +61,8 @@ def visit_generic_item(
new_scope
.
declare_local
(
name
,
op_val
.
type_type
())
case
ast
.
TypeVarTuple
(
name
):
new_scope
.
declare_local
(
name
,
TypeTupleType
(
list
(
args_iter
)).
type_type
())
#
for a, b in constraints:
# raise NotImplementedError(
)
for
a
,
b
in
constraints
:
assert
b
.
try_assign
(
a
)
# todo
new_output_type
=
instance_type
()
visit_nongeneric
(
new_scope
,
new_output_type
)
...
...
@@ -73,9 +75,20 @@ def visit_generic_item(
@
dataclass
class
StdlibVisitor
(
NodeVisitorSeq
):
python_path
:
Path
scope
:
Scope
=
field
(
default_factory
=
lambda
:
PRELUDE
)
cur_class
:
Optional
[
ResolvedConcreteType
]
=
None
typevars
:
Dict
[
str
,
BaseType
]
=
field
(
default_factory
=
dict
)
def
resolve_module_import
(
self
,
name
:
str
)
->
VarDecl
:
# tries = [
# self.python_path.parent / f"{name}.py",
# self.python_path.parent / name
# ]
# for path in tries:
# if path.exists():
# return path
# raise FileNotFoundError(f"Could not find module {name}")
return
parse_module
(
name
,
self
.
python_path
)
def
expr
(
self
)
->
ScoperExprVisitor
:
return
ScoperExprVisitor
(
self
.
scope
)
...
...
@@ -85,7 +98,7 @@ class StdlibVisitor(NodeVisitorSeq):
self
.
visit
(
stmt
)
def
visit_Assign
(
self
,
node
:
ast
.
Assign
):
self
.
scope
.
vars
[
node
.
targets
[
0
].
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
self
.
visit
(
node
.
value
))
self
.
scope
.
vars
[
node
.
targets
[
0
].
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
self
.
anno
().
visit
(
node
.
value
).
type_type
(
))
def
visit_AnnAssign
(
self
,
node
:
ast
.
AnnAssign
):
ty
=
self
.
anno
().
visit
(
node
.
annotation
)
...
...
@@ -95,10 +108,21 @@ class StdlibVisitor(NodeVisitorSeq):
self
.
scope
.
vars
[
node
.
target
.
id
]
=
VarDecl
(
VarKind
.
LOCAL
,
ty
)
def
visit_ImportFrom
(
self
,
node
:
ast
.
ImportFrom
):
pass
module
=
self
.
resolve_module_import
(
node
.
module
)
node
.
module_obj
=
module
.
type
for
alias
in
node
.
names
:
thing
=
module
.
val
.
get
(
alias
.
name
)
if
not
thing
:
from
transpiler.phases.typing.exceptions
import
UnknownModuleMemberError
raise
UnknownModuleMemberError
(
node
.
module
,
alias
.
name
)
alias
.
item_obj
=
thing
self
.
scope
.
vars
[
alias
.
asname
or
alias
.
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
thing
)
def
visit_Import
(
self
,
node
:
ast
.
Import
):
pass
for
alias
in
node
.
names
:
mod
=
self
.
resolve_module_import
(
alias
.
name
)
alias
.
module_obj
=
mod
.
type
self
.
scope
.
vars
[
alias
.
asname
or
alias
.
name
]
=
mod
def
visit_ClassDef
(
self
,
node
:
ast
.
ClassDef
):
if
existing
:
=
self
.
scope
.
get
(
node
.
name
):
...
...
@@ -109,10 +133,18 @@ class StdlibVisitor(NodeVisitorSeq):
NewType
=
base_class
(
node
.
name
)
self
.
scope
.
vars
[
node
.
name
]
=
VarDecl
(
VarKind
.
LOCAL
,
NewType
.
type_type
())
def
visit_nongeneric
(
scope
:
Scope
,
output
:
ConcreteType
):
def
visit_nongeneric
(
scope
:
Scope
,
output
:
Resolved
ConcreteType
):
cl_scope
=
scope
.
child
(
ScopeKind
.
CLASS
)
cl_scope
.
declare_local
(
"Self"
,
output
.
type_type
())
visitor
=
StdlibVisitor
(
cl_scope
,
output
)
visitor
=
StdlibVisitor
(
self
.
python_path
,
cl_scope
,
output
)
bases
=
[
self
.
anno
().
visit
(
base
)
for
base
in
node
.
bases
]
match
bases
:
case
[]:
pass
case
[
prot
]
if
is_builtin
(
prot
,
"Protocol"
):
output
.
is_protocol
=
True
case
_
:
raise
NotImplementedError
(
"parents not handled yet: "
+
", "
.
join
(
map
(
ast
.
unparse
,
node
.
bases
)))
for
stmt
in
node
.
body
:
visitor
.
visit
(
stmt
)
...
...
@@ -132,24 +164,17 @@ class StdlibVisitor(NodeVisitorSeq):
@
dataclass
(
eq
=
False
,
init
=
False
)
class
InstanceType
(
CallableInstanceType
):
def
__init__
(
self
):
super
().
__init__
(
[],
None
,
0
)
def
__init__
(
self
,
**
kwargs
):
super
().
__init__
(
**
{
"parameters"
:
None
,
"return_type"
:
None
,
**
kwargs
}
)
def
__str__
(
self
):
return
f"
{
node
.
name
}{
super
().
__str__
()
}
"
'''
class arguments(__ast.AST):
""" arguments(arg* posonlyargs, arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, arg? kwarg, expr* defaults) """'''
args
=
node
.
args
assert
args
.
posonlyargs
==
[]
#assert args.vararg is None TODO
assert
args
.
kwonlyargs
==
[]
assert
args
.
kw_defaults
==
[]
assert
args
.
kwarg
is
None
#assert args.defaults == [] TODO
for
i
,
arg
in
enumerate
(
args
.
args
):
arg
:
ast
.
arg
...
...
@@ -159,11 +184,11 @@ class StdlibVisitor(NodeVisitorSeq):
arg_name
=
"Self"
else
:
arg_name
=
f"AutoVar$
{
hash
(
arg
.
arg
)
}
"
node
.
type_params
.
append
(
ast
.
TypeVar
(
arg_name
,
None
))
# todo: bounds
node
.
type_params
.
append
(
ast
.
TypeVar
(
arg_name
,
None
))
# todo: bounds
arg
.
annotation
=
ast
.
Name
(
arg_name
,
ast
.
Load
())
else
:
if
isinstance
(
arg
.
annotation
,
ast
.
Name
)
and
(
arg
.
annotation
.
id
==
"Self"
or
#
arg.annotation.id == "Self" or
any
(
k
.
name
==
arg
.
annotation
.
id
for
k
in
node
.
type_params
)
):
# annotation is type variable so we keep it
...
...
@@ -186,13 +211,13 @@ class StdlibVisitor(NodeVisitorSeq):
return
f"FuncTypeGen$
{
node
.
name
}
"
if
cur_class_ref
is
not
None
:
def
remove_self
(
self
,
new_return_type
=
Non
e
):
def
remove_self
(
self
,
self_typ
e
):
class
BoundFuncType
(
UniqueTypeMixin
,
GenericType
):
def
name
(
self
)
->
str
:
return
f"BoundFuncType$
{
node
.
name
}
"
def
_instantiate
(
self
,
args
:
list
[
ConcreteType
])
->
GenericInstanceType
:
return
NewType
.
instantiate
(
args
).
remove_self
()
return
NewType
.
instantiate
(
args
).
remove_self
(
self_type
)
def
__str__
(
self
):
return
str
(
self
.
instantiate_default
())
...
...
@@ -213,25 +238,6 @@ class StdlibVisitor(NodeVisitorSeq):
visit_generic_item
(
visit_nongeneric
,
node
,
NewType
,
self
.
scope
,
InstanceType
,
True
)
# tc = node.type_comment # todo : lire les commetnaries de type pour les fonctions génériques sinon trouver autre chose
# arg_visitor = TypeAnnotationVisitor(self.scope.child(ScopeKind.FUNCTION), self.cur_class)
# arg_types = [arg_visitor.visit(arg.annotation or arg.arg) for arg in node.args.args]
# ret_type = arg_visitor.visit(node.returns)
# ty = FunctionType(arg_types, ret_type)
# ty.typevars = arg_visitor.typevars
# if node.args.vararg:
# ty.variadic = True
# ty.optional_at = 1 + len(node.args.args) - len(node.args.defaults)
# if self.cur_class:
# ty.is_method = True
# assert isinstance(self.cur_class, TypeType)
# if isinstance(self.cur_class.type_object, ABCMeta):
# self.cur_class.type_object.gen_methods[node.name] = lambda t: ty.gen_sub(t, self.typevars)
# else:
# self.cur_class.type_object.fields[node.name] = MemberDef(ty.gen_sub(self.cur_class.type_object, self.typevars), ())
# self.scope.vars[node.name] = VarDecl(VarKind.LOCAL, ty)
def
visit_Assert
(
self
,
node
:
ast
.
Assert
):
if
isinstance
(
node
.
test
,
ast
.
UnaryOp
)
and
isinstance
(
node
.
test
.
op
,
ast
.
Not
):
oper
=
node
.
test
.
operand
...
...
typon/trans/transpiler/phases/typing/types.py
View file @
95b8479f
import
ast
import
dataclasses
import
enum
import
typing
from
abc
import
ABC
,
abstractmethod
...
...
@@ -32,14 +34,21 @@ class UnifyMode:
UnifyMode
.
NORMAL
=
UnifyMode
()
UnifyMode
.
EXACT
=
UnifyMode
(
False
,
False
)
@
dataclass
class
BlockData
[
N
]:
node
:
N
scope
:
"Scope"
@
dataclass
(
eq
=
False
)
class
BaseType
(
ABC
):
block_data
:
Optional
[
BlockData
]
=
field
(
default
=
None
,
init
=
False
)
def
resolve
(
self
)
->
"BaseType"
:
return
self
def
type_type
(
self
)
->
"ClassTypeType"
:
return
TY_TYPE
.
instantiate
([
self
])
return
TY_TYPE
.
instantiate
([
self
.
resolve
()
])
@
abstractmethod
def
name
(
self
)
->
str
:
...
...
@@ -69,12 +78,17 @@ class BaseType(ABC):
return
(
needle
is
haystack
)
or
haystack
.
contains_internal
(
needle
)
def
try_assign
(
self
,
other
:
"BaseType"
)
->
bool
:
return
self
.
resolve
().
try_assign_internal
(
other
.
resolve
())
def
try_assign_internal
(
self
,
other
:
"BaseType"
)
->
bool
:
try
:
self
.
unify
(
other
)
return
True
except
:
return
False
def
deref
(
self
):
return
self
...
...
@@ -144,6 +158,7 @@ class ResolvedConcreteType(ConcreteType):
fields
:
Dict
[
str
,
"MemberDef"
]
=
field
(
default_factory
=
dict
,
init
=
False
)
parents
:
list
[
"ResolvedConcreteType"
]
=
field
(
default_factory
=
lambda
:
[
TY_OBJECT
],
init
=
False
)
is_protocol
:
bool
=
field
(
default
=
False
,
init
=
False
)
def
get_mro
(
self
):
"""
...
...
@@ -176,8 +191,26 @@ class ResolvedConcreteType(ConcreteType):
def
inherits
(
self
,
parent
:
BaseType
):
return
self
==
parent
or
any
(
p
.
inherits
(
parent
)
for
p
in
self
.
parents
)
def
can_receive
(
self
,
value
:
BaseType
):
return
self
==
value
def
try_assign_internal
(
self
,
other
:
BaseType
)
->
bool
:
if
self
==
other
:
return
True
if
super
().
try_assign_internal
(
other
):
return
True
if
self
.
is_protocol
:
if
isinstance
(
other
,
TypeVariable
):
other
.
unify
(
self
)
# ? maybe, we'll see if it works
return
True
assert
isinstance
(
other
,
ResolvedConcreteType
)
for
name
,
member
in
self
.
fields
.
items
():
corresponding
=
other
.
fields
.
get
(
name
)
if
corresponding
is
None
:
#raise ProtocolMismatchError(self, protocol, f"missing method {name}")
return
False
return
member
.
type
.
deref
().
try_assign
(
corresponding
.
type
.
deref
())
return
False
class
UniqueTypeMixin
:
def
unify_internal
(
self
,
other
:
"BaseType"
,
mode
:
UnifyMode
):
...
...
@@ -234,7 +267,9 @@ class GenericInstanceType(ResolvedConcreteType):
if
not
isinstance
(
other
,
GenericInstanceType
):
raise
TypeMismatchError
(
self
,
other
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
if
self
.
generic_parent
!=
other
.
generic_parent
:
raise
TypeMismatchError
(
self
,
other
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
if
not
(
isinstance
(
self
,
CallableInstanceType
)
and
isinstance
(
other
,
CallableInstanceType
)):
# methods have different generic parent types but we don't really care
raise
TypeMismatchError
(
self
,
other
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
if
len
(
self
.
generic_args
)
!=
len
(
other
.
generic_args
):
raise
TypeMismatchError
(
self
,
other
,
TypeMismatchKind
.
DIFFERENT_TYPE
)
for
a
,
b
in
zip
(
self
.
generic_args
,
other
.
generic_args
):
...
...
@@ -419,6 +454,9 @@ class TypeListType(ConcreteType):
class
UnionInstanceType
(
GenericInstanceType
):
types
:
list
[
ConcreteType
]
def
try_assign_internal
(
self
,
other
:
BaseType
)
->
bool
:
return
super
().
try_assign_internal
(
other
)
or
any
(
t
for
t
in
self
.
types
if
t
.
try_assign
(
other
))
class
UnionType
(
UniqueTypeMixin
,
GenericType
):
def
name
(
self
):
return
"Union"
...
...
@@ -440,7 +478,7 @@ TY_OPTIONAL = OptionalType()
@
typing
.
runtime_checkable
class
MethodType
(
typing
.
Protocol
):
def
remove_self
(
self
,
new_return_type
=
Non
e
)
->
...:
def
remove_self
(
self
,
self_typ
e
)
->
...:
raise
NotImplementedError
()
@
dataclass
(
eq
=
False
)
...
...
@@ -451,19 +489,31 @@ class CallableInstanceType(GenericInstanceType, MethodType):
is_variadic
:
bool
=
False
def
__post_init__
(
self
):
if
self
.
optional_at
is
None
:
if
self
.
optional_at
is
None
and
self
.
parameters
is
not
None
:
self
.
optional_at
=
len
(
self
.
parameters
)
def
remove_self
(
self
,
new_return_type
=
None
):
res
=
CallableInstanceType
(
self
.
parameters
[
1
:],
new_return_type
or
self
.
return_type
,
self
.
optional_at
-
1
,
self
.
is_variadic
)
res
.
generic_parent
=
self
.
generic_parent
res
.
generic_args
=
self
.
generic_args
return
res
#return self.generic_parent.instantiate([TypeListType(self.parameters[1:]), new_return_type or self.return_type])
def
remove_self
(
self
,
self_type
):
assert
self
.
parameters
[
0
].
try_assign
(
self_type
)
return
dataclasses
.
replace
(
self
,
parameters
=
self
.
parameters
[
1
:],
optional_at
=
self
.
optional_at
-
1
,
)
def
__str__
(
self
):
return
f"(
{
", "
.
join
(
map
(
str
,
self
.
parameters
))
}{
", *args"
if
self
.
is_variadic
else
""
}
) ->
{
self
.
return_type
}
"
return
f"(
{
", "
.
join
(
map
(
str
,
self
.
parameters
+
([
", *args"
]
if
self
.
is_variadic
else
[])))
}
) ->
{
self
.
return_type
}
"
def
try_assign_internal
(
self
,
other
:
BaseType
)
->
bool
:
if
not
isinstance
(
other
,
CallableInstanceType
):
return
False
self
.
unify
(
other
)
return
True
# @dataclass(eq=False)
# class UserFunctionInstance(CallableInstanceType):
# scope: "transpiler.phases.typing.scope.Scope" = None
# node: ast.FunctionDef = None
class
CallableType
(
UniqueTypeMixin
,
GenericType
):
def
name
(
self
):
...
...
@@ -494,15 +544,29 @@ class LambdaType(CallableType):
TY_LAMBDA
=
LambdaType
()
def
make_builtin_feature
(
name
:
str
):
class
CreatedType
(
BuiltinType
):
def
nam
e
(
self
):
return
name
class
BuiltinFeatureType
(
BuiltinType
):
@
abstractmethod
def
featur
e
(
self
):
pass
def
feature
(
self
):
return
name
CreatedType
.
__name__
=
f"BuiltinFeatureType$
{
name
}
"
return
CreatedType
()
def
__eq__
(
self
,
other
):
return
type
(
self
)
==
type
(
other
)
def
make_builtin_feature
(
name
:
str
):
match
name
:
case
"Optional"
:
return
TY_OPTIONAL
case
"Union"
:
return
TY_UNION
case
_
:
class
CreatedType
(
BuiltinFeatureType
):
def
name
(
self
):
return
name
def
feature
(
self
):
return
name
CreatedType
.
__name__
=
f"BuiltinFeatureType$
{
name
}
"
return
CreatedType
()
def
make_cpp_type
(
name
:
str
):
class
CreatedType
(
BuiltinType
):
...
...
@@ -532,4 +596,3 @@ class ClassType(UniqueTypeMixin, GenericType):
return
ClassTypeType
(
*
args
)
TY_TYPE
=
ClassType
()
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