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)
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
"""
# 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)
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
"""
expression(wgn, mod, inp.test)
with wgn.if_():
for stat in inp.statements:
statement(wgn, mod, stat)
statement(wgn, mod, fun, stat)
if inp.else_statements:
raise NotImplementedError
@ -391,16 +401,16 @@ def statement_if(wgn: WasmGenerator, mod: ourlang.Module, inp: ourlang.Statement
# for stat in inp.else_statements:
# 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
"""
if isinstance(inp, ourlang.StatementReturn):
statement_return(wgn, mod, inp)
statement_return(wgn, mod, fun, inp)
return
if isinstance(inp, ourlang.StatementIf):
statement_if(wgn, mod, inp)
statement_if(wgn, mod, fun, inp)
return
if isinstance(inp, ourlang.StatementPass):
@ -443,7 +453,7 @@ def function(mod: ourlang.Module, inp: ourlang.Function) -> wasm.Function:
_generate_struct_constructor(wgn, inp)
else:
for stat in inp.statements:
statement(wgn, mod, stat)
statement(wgn, mod, inp, stat)
return wasm.Function(
inp.name,