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
4979ed0e
Commit
4979ed0e
authored
Aug 19, 2023
by
Tom Niget
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for for-else and while-else
parent
85b27174
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
35 additions
and
11 deletions
+35
-11
trans/transpiler/phases/emit_cpp/function.py
trans/transpiler/phases/emit_cpp/function.py
+20
-3
trans/transpiler/phases/typing/block.py
trans/transpiler/phases/typing/block.py
+10
-4
trans/transpiler/phases/typing/scope.py
trans/transpiler/phases/typing/scope.py
+5
-4
No files found.
trans/transpiler/phases/emit_cpp/function.py
View file @
4979ed0e
...
...
@@ -26,12 +26,19 @@ class FunctionVisitor(BlockVisitor):
def
visit_For
(
self
,
node
:
ast
.
For
)
->
Iterable
[
str
]:
if
not
isinstance
(
node
.
target
,
ast
.
Name
):
raise
NotImplementedError
(
node
)
if
node
.
orelse
:
yield
"auto"
yield
node
.
orelse_variable
yield
"= true;"
yield
f"for (auto
{
node
.
target
.
id
}
: "
yield
from
self
.
expr
().
visit
(
node
.
iter
)
yield
")"
yield
from
self
.
emit_block
(
node
.
inner_scope
,
node
.
body
)
yield
from
self
.
emit_block
(
node
.
inner_scope
,
node
.
body
)
# TODO: why not reuse the scope used for analysis? same in while
if
node
.
orelse
:
raise
NotImplementedError
(
node
,
"orelse"
)
yield
"if ("
yield
node
.
orelse_variable
yield
")"
yield
from
self
.
emit_block
(
node
.
inner_scope
,
node
.
orelse
)
def
visit_If
(
self
,
node
:
ast
.
If
)
->
Iterable
[
str
]:
yield
"if ("
...
...
@@ -58,12 +65,19 @@ class FunctionVisitor(BlockVisitor):
yield
";"
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
:
raise
NotImplementedError
(
node
,
"orelse"
)
yield
"if ("
yield
node
.
orelse_variable
yield
")"
yield
from
self
.
emit_block
(
node
.
inner_scope
,
node
.
orelse
)
def
visit_Global
(
self
,
node
:
ast
.
Global
)
->
Iterable
[
str
]:
yield
""
...
...
@@ -84,6 +98,9 @@ class FunctionVisitor(BlockVisitor):
yield
"}"
def
visit_Break
(
self
,
node
:
ast
.
Break
)
->
Iterable
[
str
]:
if
(
loop
:
=
self
.
scope
.
is_in_loop
()).
orelse
:
yield
loop
.
orelse_variable
yield
" = false;"
yield
"break;"
def
visit_Try
(
self
,
node
:
ast
.
Try
)
->
Iterable
[
str
]:
...
...
trans/transpiler/phases/typing/block.py
View file @
4979ed0e
...
...
@@ -226,14 +226,17 @@ class ScoperBlockVisitor(ScoperVisitor):
def
visit_While
(
self
,
node
:
ast
.
While
):
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
scope
.
is_loop
=
Tru
e
scope
.
is_loop
=
nod
e
node
.
inner_scope
=
scope
self
.
expr
().
visit
(
node
.
test
)
body_scope
=
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
body_visitor
=
ScoperBlockVisitor
(
body_scope
,
self
.
root_decls
)
body_visitor
.
visit_block
(
node
.
body
)
if
node
.
orelse
:
raise
NotImplementedError
(
node
.
orelse
)
orelse_scope
=
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
orelse_visitor
=
ScoperBlockVisitor
(
orelse_scope
,
self
.
root_decls
)
orelse_visitor
.
visit_block
(
node
.
orelse
)
node
.
orelse_variable
=
f"orelse_
{
id
(
node
)
}
"
def
visit_PlainBlock
(
self
,
node
:
PlainBlock
):
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
...
...
@@ -243,7 +246,7 @@ class ScoperBlockVisitor(ScoperVisitor):
def
visit_For
(
self
,
node
:
ast
.
For
):
scope
=
self
.
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
scope
.
is_loop
=
Tru
e
scope
.
is_loop
=
nod
e
node
.
inner_scope
=
scope
assert
isinstance
(
node
.
target
,
ast
.
Name
)
var_var
=
TypeVariable
()
...
...
@@ -256,7 +259,10 @@ class ScoperBlockVisitor(ScoperVisitor):
body_visitor
=
ScoperBlockVisitor
(
body_scope
,
self
.
root_decls
)
body_visitor
.
visit_block
(
node
.
body
)
if
node
.
orelse
:
raise
NotImplementedError
(
node
.
orelse
)
orelse_scope
=
scope
.
child
(
ScopeKind
.
FUNCTION_INNER
)
orelse_visitor
=
ScoperBlockVisitor
(
orelse_scope
,
self
.
root_decls
)
orelse_visitor
.
visit_block
(
node
.
orelse
)
node
.
orelse_variable
=
f"orelse_
{
id
(
node
)
}
"
def
visit_Expr
(
self
,
node
:
ast
.
Expr
):
self
.
expr
().
visit
(
node
.
value
)
...
...
trans/transpiler/phases/typing/scope.py
View file @
4979ed0e
import
ast
from
dataclasses
import
field
,
dataclass
from
enum
import
Enum
from
typing
import
Optional
,
Dict
,
List
,
Any
...
...
@@ -55,7 +56,7 @@ class Scope:
obj_type
:
Optional
[
BaseType
]
=
None
has_return
:
bool
=
False
class_
:
Optional
[
"Scope"
]
=
None
is_loop
:
bool
=
Fals
e
is_loop
:
Optional
[
ast
.
For
|
ast
.
While
]
=
Non
e
@
staticmethod
def
make_global
():
...
...
@@ -63,12 +64,12 @@ class Scope:
res
.
global_scope
=
res
return
res
def
is_in_loop
(
self
)
->
bool
:
def
is_in_loop
(
self
)
->
Optional
[
ast
.
For
|
ast
.
While
]
:
if
self
.
is_loop
:
return
True
return
self
.
is_loop
if
self
.
parent
is
not
None
and
self
.
kind
!=
ScopeKind
.
FUNCTION
:
return
self
.
parent
.
is_in_loop
()
return
Fals
e
return
Non
e
def
child
(
self
,
kind
:
ScopeKind
):
res
=
Scope
(
self
,
kind
,
self
.
function
,
self
.
global_scope
)
...
...
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