Support tail calls

This commit is contained in:
Johan B.W. de Vries 2025-05-25 14:42:31 +02:00
parent 2c2a96c8a7
commit d017ebe096

View File

@ -369,21 +369,31 @@ def expression(wgn: WasmGenerator, mod: ourlang.Module, inp: ourlang.Expression)
raise NotImplementedError(expression, inp) raise NotImplementedError(expression, inp)
def statement_return(wgn: WasmGenerator, mod: ourlang.Module, inp: ourlang.StatementReturn) -> None: def statement_return(wgn: WasmGenerator, mod: ourlang.Module, fun: ourlang.Function, inp: ourlang.StatementReturn) -> None:
""" """
Compile: Return statement Compile: Return statement
""" """
# Support tail calls
# https://github.com/WebAssembly/tail-call
# These help a lot with some functional programming techniques
if isinstance(inp.value, ourlang.FunctionCall) and inp.value.function is fun:
for arg in inp.value.arguments:
expression(wgn, mod, arg)
wgn.add_statement('return_call', '${}'.format(inp.value.function.name))
return
expression(wgn, mod, inp.value) expression(wgn, mod, inp.value)
wgn.return_() wgn.return_()
def statement_if(wgn: WasmGenerator, mod: ourlang.Module, inp: ourlang.StatementIf) -> None: def statement_if(wgn: WasmGenerator, mod: ourlang.Module, fun: ourlang.Function, inp: ourlang.StatementIf) -> None:
""" """
Compile: If statement Compile: If statement
""" """
expression(wgn, mod, inp.test) expression(wgn, mod, inp.test)
with wgn.if_(): with wgn.if_():
for stat in inp.statements: for stat in inp.statements:
statement(wgn, mod, stat) statement(wgn, mod, fun, stat)
if inp.else_statements: if inp.else_statements:
raise NotImplementedError raise NotImplementedError
@ -391,16 +401,16 @@ def statement_if(wgn: WasmGenerator, mod: ourlang.Module, inp: ourlang.Statement
# for stat in inp.else_statements: # for stat in inp.else_statements:
# statement(wgn, stat) # statement(wgn, stat)
def statement(wgn: WasmGenerator, mod: ourlang.Module, inp: ourlang.Statement) -> None: def statement(wgn: WasmGenerator, mod: ourlang.Module, fun: ourlang.Function, inp: ourlang.Statement) -> None:
""" """
Compile: any statement Compile: any statement
""" """
if isinstance(inp, ourlang.StatementReturn): if isinstance(inp, ourlang.StatementReturn):
statement_return(wgn, mod, inp) statement_return(wgn, mod, fun, inp)
return return
if isinstance(inp, ourlang.StatementIf): if isinstance(inp, ourlang.StatementIf):
statement_if(wgn, mod, inp) statement_if(wgn, mod, fun, inp)
return return
if isinstance(inp, ourlang.StatementPass): if isinstance(inp, ourlang.StatementPass):
@ -443,7 +453,7 @@ def function(mod: ourlang.Module, inp: ourlang.Function) -> wasm.Function:
_generate_struct_constructor(wgn, inp) _generate_struct_constructor(wgn, inp)
else: else:
for stat in inp.statements: for stat in inp.statements:
statement(wgn, mod, stat) statement(wgn, mod, inp, stat)
return wasm.Function( return wasm.Function(
inp.name, inp.name,