Skip to content

Commit

Permalink
Remove redundant assignments with nested ifs (closes hylang#842)
Browse files Browse the repository at this point in the history
  • Loading branch information
refi64 committed Aug 25, 2015
1 parent 2c2d679 commit 7f89886
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions hy/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ def __init__(self, module_name):
self.anon_var_count = 0
self.imports = defaultdict(set)
self.module_name = module_name
self.temp_if = None
if not module_name.startswith("hy.core"):
# everything in core needs to be explicit.
load_stdlib()
Expand Down Expand Up @@ -998,22 +999,30 @@ def _compile_catch_expression(self, expr, var):

@builds("if")
@checkargs(min=2, max=3)
def compile_if(self, expression):
def compile_if(self, expression, temp=None):
expression.pop(0)
cond = self.compile(expression.pop(0))

body = self.compile(expression.pop(0))
orel = Result()
nested = root = False
if expression:
orel = self.compile(expression.pop(0))
orel_expr = expression.pop(0)
if isinstance(orel_expr, HyExpression) and isinstance(orel_expr[0],
HySymbol) and orel_expr[0] == 'if':
# Nested ifs: don't waste temporaries
root = self.temp_if is None
nested = True
self.temp_if = self.temp_if or self.get_anon_var()
orel = self.compile(orel_expr)

# We want to hoist the statements from the condition
ret = cond

if body.stmts or orel.stmts:
# We have statements in our bodies
# Get a temporary variable for the result storage
var = self.get_anon_var()
var = self.temp_if or self.get_anon_var()
name = ast.Name(id=ast_str(var), arg=ast_str(var),
ctx=ast.Store(),
lineno=expression.start_line,
Expand All @@ -1026,10 +1035,12 @@ def compile_if(self, expression):
col_offset=expression.start_column)

# and of the else clause
orel += ast.Assign(targets=[name],
value=orel.force_expr,
lineno=expression.start_line,
col_offset=expression.start_column)
if not nested or not orel.stmts or (not root and
var != self.temp_if):
orel += ast.Assign(targets=[name],
value=orel.force_expr,
lineno=expression.start_line,
col_offset=expression.start_column)

# Then build the if
ret += ast.If(test=ret.force_expr,
Expand All @@ -1052,6 +1063,10 @@ def compile_if(self, expression):
orelse=orel.force_expr,
lineno=expression.start_line,
col_offset=expression.start_column)

if root:
self.temp_if = None

return ret

@builds("break")
Expand Down

0 comments on commit 7f89886

Please sign in to comment.