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:
|
def codegen_inner(self) -> str:
|
||||||
return unwrap_r(self.eliminate(Variable('$'))).codegen()
|
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:
|
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:
|
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:
|
def __repr__(self) -> str:
|
||||||
return '{ ' + ', '.join('"' + repr(repr(p))[1:-1] + '" : ' + repr(e) for (p, e) in self.forms) + ' }'
|
return '{ ' + ', '.join('"' + repr(repr(p))[1:-1] + '" : ' + repr(e) for (p, e) in self.forms) + ' }'
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue