Add special case to improve quality of generated code for simple functions
This commit is contained in:
parent
79deebabf4
commit
55fa7add0e
34
ir.py
34
ir.py
|
@ -116,10 +116,40 @@ class Function:
|
|||
|
||||
def codegen_inner(self) -> str:
|
||||
return unwrap_r(self.eliminate(Variable('$'))).codegen()
|
||||
def try_codegen_sp(self) -> Option[Tuple[str, str]]:
|
||||
""" A special-case of codegen inner (see description)
|
||||
|
||||
In certain cases, starting a function with a full match tree may be unnecessary.
|
||||
Specifically, if there exists only one possible branch and that branch binds only
|
||||
one value and that value is equal to the whole entire input, rather than assigning
|
||||
that input to a new variable, we may simply use argument variable instead.
|
||||
|
||||
This method returns the generated code for the inner branch in such a case.
|
||||
Additionally, the second string returned represents the name of the variable which
|
||||
ought to be bound as the argument. If the argument is unused, this will be "$".
|
||||
"""
|
||||
match self.forms:
|
||||
case [(patt, expr)]: # A single possible branch
|
||||
match patt.bindings():
|
||||
case []: # Binds nothing
|
||||
return Some((expr.codegen(), '$'))
|
||||
case [(var, [])]: # Binds a single variable to the entire input
|
||||
return Some((expr.codegen(), var))
|
||||
return None
|
||||
def codegen(self) -> str:
|
||||
return '$=>' + self.codegen_inner()
|
||||
match self.try_codegen_sp():
|
||||
case Some((codegen, var)):
|
||||
return f'{var}=>{codegen}'
|
||||
case None:
|
||||
return '$=>' + self.codegen_inner()
|
||||
raise Exception('Unreachable')
|
||||
def codegen_named(self, name) -> str:
|
||||
return f'function {name}($){{return {self.codegen_inner()}}}'
|
||||
match self.try_codegen_sp():
|
||||
case Some((codegen, var)):
|
||||
return f'function {name}({var}){{return {codegen}}}'
|
||||
case None:
|
||||
return f'function {name}($){{return {self.codegen_inner()}}}'
|
||||
raise Exception('Unreachable')
|
||||
def __repr__(self) -> str:
|
||||
return '{ ' + ', '.join('"' + repr(repr(p))[1:-1] + '" : ' + repr(e) for (p, e) in self.forms) + ' }'
|
||||
|
||||
|
|
Loading…
Reference in a new issue