|
|
|
@ -158,9 +158,11 @@ class FunctionVyper: |
|
|
|
|
|
|
|
|
|
if body and not isinstance(body[0], Pass): |
|
|
|
|
self._function.is_implemented = True |
|
|
|
|
self._function.is_empty = False |
|
|
|
|
self._parse_cfg(body) |
|
|
|
|
else: |
|
|
|
|
self._function.is_implemented = False |
|
|
|
|
self._function.is_empty = True |
|
|
|
|
|
|
|
|
|
for local_var_parser in self._local_variables_parser: |
|
|
|
|
local_var_parser.analyze(self._function) |
|
|
|
@ -218,264 +220,257 @@ class FunctionVyper: |
|
|
|
|
################################################################################### |
|
|
|
|
################################################################################### |
|
|
|
|
|
|
|
|
|
def _parse_cfg(self, cfg: Dict) -> None: |
|
|
|
|
def _parse_cfg(self, cfg: List[ASTNode]) -> None: |
|
|
|
|
|
|
|
|
|
entry_node = self._new_node(NodeType.ENTRYPOINT, "-1:-1:-1", self.underlying_function) |
|
|
|
|
self._function.entry_point = entry_node.underlying_node |
|
|
|
|
scope = Scope(True, False, self.underlying_function) |
|
|
|
|
|
|
|
|
|
if cfg: |
|
|
|
|
self._function.is_empty = False |
|
|
|
|
curr_node = entry_node |
|
|
|
|
for expr in cfg: |
|
|
|
|
|
|
|
|
|
def parse_statement(curr_node, expr): |
|
|
|
|
if isinstance(expr, AnnAssign): |
|
|
|
|
local_var = LocalVariable() |
|
|
|
|
local_var.set_function(self._function) |
|
|
|
|
local_var.set_offset(expr.src, self._function.compilation_unit) |
|
|
|
|
|
|
|
|
|
local_var_parser = LocalVariableVyper(local_var, expr) |
|
|
|
|
self._add_local_variable(local_var_parser) |
|
|
|
|
|
|
|
|
|
new_node = self._new_node(NodeType.VARIABLE, expr.src, scope) |
|
|
|
|
if expr.value is not None: |
|
|
|
|
local_var.initialized = True |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
new_node.underlying_node.add_variable_declaration(local_var) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = entry_node |
|
|
|
|
for expr in cfg: |
|
|
|
|
|
|
|
|
|
curr_node = new_node |
|
|
|
|
def parse_statement(curr_node, expr): |
|
|
|
|
if isinstance(expr, AnnAssign): |
|
|
|
|
local_var = LocalVariable() |
|
|
|
|
local_var.set_function(self._function) |
|
|
|
|
local_var.set_offset(expr.src, self._function.compilation_unit) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, (AugAssign, Assign)): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
local_var_parser = LocalVariableVyper(local_var, expr) |
|
|
|
|
self._add_local_variable(local_var_parser) |
|
|
|
|
|
|
|
|
|
curr_node = new_node |
|
|
|
|
new_node = self._new_node(NodeType.VARIABLE, expr.src, scope) |
|
|
|
|
if expr.value is not None: |
|
|
|
|
local_var.initialized = True |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
new_node.underlying_node.add_variable_declaration(local_var) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, Expr): |
|
|
|
|
# TODO This is a workaround to handle Vyper putting payable/view in the function body... |
|
|
|
|
if not isinstance(expr.value, Name): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
|
|
|
|
|
curr_node = new_node |
|
|
|
|
elif isinstance(expr, (AugAssign, Assign)): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, For): |
|
|
|
|
curr_node = new_node |
|
|
|
|
|
|
|
|
|
node_startLoop = self._new_node(NodeType.STARTLOOP, expr.src, scope) |
|
|
|
|
link_underlying_nodes(curr_node, node_startLoop) |
|
|
|
|
elif isinstance(expr, Expr): |
|
|
|
|
# TODO This is a workaround to handle Vyper putting payable/view in the function body... |
|
|
|
|
if not isinstance(expr.value, Name): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
|
|
|
|
|
local_var = LocalVariable() |
|
|
|
|
local_var.set_function(self._function) |
|
|
|
|
local_var.set_offset(expr.src, self._function.compilation_unit) |
|
|
|
|
curr_node = new_node |
|
|
|
|
|
|
|
|
|
counter_var = AnnAssign( |
|
|
|
|
expr.target.src, |
|
|
|
|
expr.target.node_id, |
|
|
|
|
target=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
annotation=Name("-1:-1:-1", -1, "uint256"), |
|
|
|
|
value=Int("-1:-1:-1", -1, 0), |
|
|
|
|
) |
|
|
|
|
local_var_parser = LocalVariableVyper(local_var, counter_var) |
|
|
|
|
self._add_local_variable(local_var_parser) |
|
|
|
|
counter_node = self._new_node(NodeType.VARIABLE, expr.src, scope) |
|
|
|
|
local_var.initialized = True |
|
|
|
|
counter_node.add_unparsed_expression(counter_var.value) |
|
|
|
|
counter_node.underlying_node.add_variable_declaration(local_var) |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(node_startLoop, counter_node) |
|
|
|
|
|
|
|
|
|
node_condition = None |
|
|
|
|
if isinstance(expr.iter, (Attribute, Name)): |
|
|
|
|
# HACK |
|
|
|
|
# The loop variable is not annotated so we infer its type by looking at the type of the iterator |
|
|
|
|
if isinstance(expr.iter, Attribute): # state variable |
|
|
|
|
iter_expr = expr.iter |
|
|
|
|
loop_iterator = list( |
|
|
|
|
filter( |
|
|
|
|
lambda x: x._variable.name == iter_expr.attr, |
|
|
|
|
self._contract_parser._variables_parser, |
|
|
|
|
) |
|
|
|
|
)[0] |
|
|
|
|
|
|
|
|
|
else: # local variable |
|
|
|
|
iter_expr = expr.iter |
|
|
|
|
loop_iterator = list( |
|
|
|
|
filter( |
|
|
|
|
lambda x: x._variable.name == iter_expr.id, |
|
|
|
|
self._local_variables_parser, |
|
|
|
|
) |
|
|
|
|
)[0] |
|
|
|
|
|
|
|
|
|
# TODO use expr.src instead of -1:-1:1? |
|
|
|
|
cond_expr = Compare( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
left=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
op="<=", |
|
|
|
|
right=Call( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
func=Name("-1:-1:-1", -1, "len"), |
|
|
|
|
args=[iter_expr], |
|
|
|
|
keywords=[], |
|
|
|
|
keyword=None, |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
node_condition = self._new_node(NodeType.IFLOOP, expr.src, scope) |
|
|
|
|
node_condition.add_unparsed_expression(cond_expr) |
|
|
|
|
|
|
|
|
|
if loop_iterator._elem_to_parse.value.id == "DynArray": |
|
|
|
|
loop_var_annotation = ( |
|
|
|
|
loop_iterator._elem_to_parse.slice.value.elements[0] |
|
|
|
|
elif isinstance(expr, For): |
|
|
|
|
|
|
|
|
|
node_startLoop = self._new_node(NodeType.STARTLOOP, expr.src, scope) |
|
|
|
|
link_underlying_nodes(curr_node, node_startLoop) |
|
|
|
|
|
|
|
|
|
local_var = LocalVariable() |
|
|
|
|
local_var.set_function(self._function) |
|
|
|
|
local_var.set_offset(expr.src, self._function.compilation_unit) |
|
|
|
|
|
|
|
|
|
counter_var = AnnAssign( |
|
|
|
|
expr.target.src, |
|
|
|
|
expr.target.node_id, |
|
|
|
|
target=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
annotation=Name("-1:-1:-1", -1, "uint256"), |
|
|
|
|
value=Int("-1:-1:-1", -1, 0), |
|
|
|
|
) |
|
|
|
|
local_var_parser = LocalVariableVyper(local_var, counter_var) |
|
|
|
|
self._add_local_variable(local_var_parser) |
|
|
|
|
counter_node = self._new_node(NodeType.VARIABLE, expr.src, scope) |
|
|
|
|
local_var.initialized = True |
|
|
|
|
counter_node.add_unparsed_expression(counter_var.value) |
|
|
|
|
counter_node.underlying_node.add_variable_declaration(local_var) |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(node_startLoop, counter_node) |
|
|
|
|
|
|
|
|
|
node_condition = None |
|
|
|
|
if isinstance(expr.iter, (Attribute, Name)): |
|
|
|
|
# HACK |
|
|
|
|
# The loop variable is not annotated so we infer its type by looking at the type of the iterator |
|
|
|
|
if isinstance(expr.iter, Attribute): # state variable |
|
|
|
|
iter_expr = expr.iter |
|
|
|
|
loop_iterator = list( |
|
|
|
|
filter( |
|
|
|
|
lambda x: x._variable.name == iter_expr.attr, |
|
|
|
|
self._contract_parser._variables_parser, |
|
|
|
|
) |
|
|
|
|
else: |
|
|
|
|
loop_var_annotation = loop_iterator._elem_to_parse.value |
|
|
|
|
)[0] |
|
|
|
|
|
|
|
|
|
else: # local variable |
|
|
|
|
iter_expr = expr.iter |
|
|
|
|
loop_iterator = list( |
|
|
|
|
filter( |
|
|
|
|
lambda x: x._variable.name == iter_expr.id, |
|
|
|
|
self._local_variables_parser, |
|
|
|
|
) |
|
|
|
|
)[0] |
|
|
|
|
|
|
|
|
|
value = Subscript( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
value=Name("-1:-1:-1", -1, loop_iterator._variable.name), |
|
|
|
|
slice=Index( |
|
|
|
|
"-1:-1:-1", -1, value=Name("-1:-1:-1", -1, "counter_var") |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
loop_var = AnnAssign( |
|
|
|
|
expr.target.src, |
|
|
|
|
expr.target.node_id, |
|
|
|
|
target=expr.target, |
|
|
|
|
annotation=loop_var_annotation, |
|
|
|
|
value=value, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr.iter, Call): # range |
|
|
|
|
range_val = expr.iter.args[0] |
|
|
|
|
cond_expr = Compare( |
|
|
|
|
# TODO use expr.src instead of -1:-1:1? |
|
|
|
|
cond_expr = Compare( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
left=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
op="<=", |
|
|
|
|
right=Call( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
left=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
op="<=", |
|
|
|
|
right=range_val, |
|
|
|
|
) |
|
|
|
|
node_condition = self._new_node(NodeType.IFLOOP, expr.src, scope) |
|
|
|
|
node_condition.add_unparsed_expression(cond_expr) |
|
|
|
|
loop_var = AnnAssign( |
|
|
|
|
expr.target.src, |
|
|
|
|
expr.target.node_id, |
|
|
|
|
target=expr.target, |
|
|
|
|
annotation=Name("-1:-1:-1", -1, "uint256"), |
|
|
|
|
value=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
) |
|
|
|
|
func=Name("-1:-1:-1", -1, "len"), |
|
|
|
|
args=[iter_expr], |
|
|
|
|
keywords=[], |
|
|
|
|
keyword=None, |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
node_condition = self._new_node(NodeType.IFLOOP, expr.src, scope) |
|
|
|
|
node_condition.add_unparsed_expression(cond_expr) |
|
|
|
|
|
|
|
|
|
if loop_iterator._elem_to_parse.value.id == "DynArray": |
|
|
|
|
loop_var_annotation = loop_iterator._elem_to_parse.slice.value.elements[ |
|
|
|
|
0 |
|
|
|
|
] |
|
|
|
|
else: |
|
|
|
|
raise NotImplementedError |
|
|
|
|
|
|
|
|
|
# link |
|
|
|
|
link_underlying_nodes(counter_node, node_condition) |
|
|
|
|
loop_var_annotation = loop_iterator._elem_to_parse.value |
|
|
|
|
|
|
|
|
|
# We update the index variable or range variable in the loop body |
|
|
|
|
expr.body.insert(0, loop_var) |
|
|
|
|
body_node = None |
|
|
|
|
new_node = node_condition |
|
|
|
|
for stmt in expr.body: |
|
|
|
|
body_node = parse_statement(new_node, stmt) |
|
|
|
|
new_node = body_node |
|
|
|
|
|
|
|
|
|
node_endLoop = self._new_node(NodeType.ENDLOOP, expr.src, scope) |
|
|
|
|
value = Subscript( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
value=Name("-1:-1:-1", -1, loop_iterator._variable.name), |
|
|
|
|
slice=Index("-1:-1:-1", -1, value=Name("-1:-1:-1", -1, "counter_var")), |
|
|
|
|
) |
|
|
|
|
loop_var = AnnAssign( |
|
|
|
|
expr.target.src, |
|
|
|
|
expr.target.node_id, |
|
|
|
|
target=expr.target, |
|
|
|
|
annotation=loop_var_annotation, |
|
|
|
|
value=value, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
loop_increment = AugAssign( |
|
|
|
|
elif isinstance(expr.iter, Call): # range |
|
|
|
|
range_val = expr.iter.args[0] |
|
|
|
|
cond_expr = Compare( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
target=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
op="+=", |
|
|
|
|
value=Int("-1:-1:-1", -1, 1), |
|
|
|
|
left=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
op="<=", |
|
|
|
|
right=range_val, |
|
|
|
|
) |
|
|
|
|
node_condition = self._new_node(NodeType.IFLOOP, expr.src, scope) |
|
|
|
|
node_condition.add_unparsed_expression(cond_expr) |
|
|
|
|
loop_var = AnnAssign( |
|
|
|
|
expr.target.src, |
|
|
|
|
expr.target.node_id, |
|
|
|
|
target=expr.target, |
|
|
|
|
annotation=Name("-1:-1:-1", -1, "uint256"), |
|
|
|
|
value=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
) |
|
|
|
|
node_increment = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
node_increment.add_unparsed_expression(loop_increment) |
|
|
|
|
link_underlying_nodes(node_increment, node_condition) |
|
|
|
|
|
|
|
|
|
if body_node is not None: |
|
|
|
|
link_underlying_nodes(body_node, node_increment) |
|
|
|
|
else: |
|
|
|
|
raise NotImplementedError |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(counter_node, node_condition) |
|
|
|
|
|
|
|
|
|
# We update the index variable or range variable in the loop body |
|
|
|
|
expr.body.insert(0, loop_var) |
|
|
|
|
body_node = None |
|
|
|
|
new_node = node_condition |
|
|
|
|
for stmt in expr.body: |
|
|
|
|
body_node = parse_statement(new_node, stmt) |
|
|
|
|
new_node = body_node |
|
|
|
|
|
|
|
|
|
node_endLoop = self._new_node(NodeType.ENDLOOP, expr.src, scope) |
|
|
|
|
|
|
|
|
|
loop_increment = AugAssign( |
|
|
|
|
"-1:-1:-1", |
|
|
|
|
-1, |
|
|
|
|
target=Name("-1:-1:-1", -1, "counter_var"), |
|
|
|
|
op="+=", |
|
|
|
|
value=Int("-1:-1:-1", -1, 1), |
|
|
|
|
) |
|
|
|
|
node_increment = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
node_increment.add_unparsed_expression(loop_increment) |
|
|
|
|
link_underlying_nodes(node_increment, node_condition) |
|
|
|
|
|
|
|
|
|
if body_node is not None: |
|
|
|
|
link_underlying_nodes(body_node, node_increment) |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(node_condition, node_endLoop) |
|
|
|
|
|
|
|
|
|
curr_node = node_endLoop |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, Continue): |
|
|
|
|
pass |
|
|
|
|
elif isinstance(expr, Break): |
|
|
|
|
pass |
|
|
|
|
elif isinstance(expr, Return): |
|
|
|
|
new_node = self._new_node(NodeType.RETURN, expr.src, scope) |
|
|
|
|
if expr.value is not None: |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(node_condition, node_endLoop) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
|
|
|
|
|
curr_node = node_endLoop |
|
|
|
|
elif isinstance(expr, Assert): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, Continue): |
|
|
|
|
pass |
|
|
|
|
elif isinstance(expr, Break): |
|
|
|
|
pass |
|
|
|
|
elif isinstance(expr, Return): |
|
|
|
|
new_node = self._new_node(NodeType.RETURN, expr.src, scope) |
|
|
|
|
if expr.value is not None: |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
elif isinstance(expr, Log): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, Assert): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
elif isinstance(expr, If): |
|
|
|
|
condition_node = self._new_node(NodeType.IF, expr.test.src, scope) |
|
|
|
|
condition_node.add_unparsed_expression(expr.test) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, Log): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr.value) |
|
|
|
|
endIf_node = self._new_node(NodeType.ENDIF, expr.src, scope) |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
true_node = None |
|
|
|
|
new_node = condition_node |
|
|
|
|
for stmt in expr.body: |
|
|
|
|
true_node = parse_statement(new_node, stmt) |
|
|
|
|
new_node = true_node |
|
|
|
|
# link_underlying_nodes(condition_node, true_node) |
|
|
|
|
link_underlying_nodes(true_node, endIf_node) |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, If): |
|
|
|
|
condition_node = self._new_node(NodeType.IF, expr.test.src, scope) |
|
|
|
|
condition_node.add_unparsed_expression(expr.test) |
|
|
|
|
false_node = None |
|
|
|
|
new_node = condition_node |
|
|
|
|
for stmt in expr.orelse: |
|
|
|
|
false_node = parse_statement(new_node, stmt) |
|
|
|
|
new_node = false_node |
|
|
|
|
|
|
|
|
|
endIf_node = self._new_node(NodeType.ENDIF, expr.src, scope) |
|
|
|
|
if false_node is not None: |
|
|
|
|
# link_underlying_nodes(condition_node, false_node) |
|
|
|
|
link_underlying_nodes(false_node, endIf_node) |
|
|
|
|
|
|
|
|
|
true_node = None |
|
|
|
|
new_node = condition_node |
|
|
|
|
for stmt in expr.body: |
|
|
|
|
true_node = parse_statement(new_node, stmt) |
|
|
|
|
new_node = true_node |
|
|
|
|
# link_underlying_nodes(condition_node, true_node) |
|
|
|
|
link_underlying_nodes(true_node, endIf_node) |
|
|
|
|
else: |
|
|
|
|
link_underlying_nodes(condition_node, endIf_node) |
|
|
|
|
|
|
|
|
|
false_node = None |
|
|
|
|
new_node = condition_node |
|
|
|
|
for stmt in expr.orelse: |
|
|
|
|
false_node = parse_statement(new_node, stmt) |
|
|
|
|
new_node = false_node |
|
|
|
|
link_underlying_nodes(curr_node, condition_node) |
|
|
|
|
curr_node = endIf_node |
|
|
|
|
|
|
|
|
|
if false_node is not None: |
|
|
|
|
# link_underlying_nodes(condition_node, false_node) |
|
|
|
|
link_underlying_nodes(false_node, endIf_node) |
|
|
|
|
elif isinstance(expr, Pass): |
|
|
|
|
pass |
|
|
|
|
elif isinstance(expr, Raise): |
|
|
|
|
new_node = self._new_node(NodeType.EXPRESSION, expr.src, scope) |
|
|
|
|
new_node.add_unparsed_expression(expr) |
|
|
|
|
link_underlying_nodes(curr_node, new_node) |
|
|
|
|
curr_node = new_node |
|
|
|
|
|
|
|
|
|
else: |
|
|
|
|
link_underlying_nodes(condition_node, endIf_node) |
|
|
|
|
|
|
|
|
|
link_underlying_nodes(curr_node, condition_node) |
|
|
|
|
curr_node = endIf_node |
|
|
|
|
|
|
|
|
|
elif isinstance(expr, Pass): |
|
|
|
|
pass |
|
|
|
|
elif isinstance(expr, Raise): |
|
|
|
|
print(expr) |
|
|
|
|
# TODO |
|
|
|
|
# assert False |
|
|
|
|
pass |
|
|
|
|
else: |
|
|
|
|
print(f"isinstance(expr, {expr.__class__.__name__})") |
|
|
|
|
assert False |
|
|
|
|
return curr_node |
|
|
|
|
else: |
|
|
|
|
raise ParsingError(f"Statement not parsed {expr.__class__.__name__} {expr}") |
|
|
|
|
|
|
|
|
|
curr_node = parse_statement(curr_node, expr) |
|
|
|
|
# self._parse_block(cfg, node, self.underlying_function) |
|
|
|
|
else: |
|
|
|
|
self._function.is_empty = True |
|
|
|
|
return curr_node |
|
|
|
|
|
|
|
|
|
curr_node = parse_statement(curr_node, expr) |
|
|
|
|
|
|
|
|
|
# endregion |
|
|
|
|
################################################################################### |
|
|
|
|