diff --git a/README.md b/README.md index 662756c..20aad29 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,9 @@ PRs are welcome. ### Some of the things I know are missing -- no case expressions -- block expressions aren't supported yet - no destructuring/pattern matching in let - no let assert +- no case expressions - label aliases aren't supported yet (ie `fn foo(bar bas: Str)`) - const definitions aren't supported yet (module.constants) - type aliases aren't supported yet (module.type_aliases) diff --git a/src/compiler/internal/transformer/statements.gleam b/src/compiler/internal/transformer/statements.gleam index eb522fe..e1e700a 100644 --- a/src/compiler/internal/transformer/statements.gleam +++ b/src/compiler/internal/transformer/statements.gleam @@ -141,6 +141,8 @@ fn transform_expression( glance.Fn(arguments:, return_annotation: _, body:) -> transform_fn(context, arguments, body) + glance.Block(statements) -> transform_block(context, statements) + glance.TupleIndex(tuple, index) -> { transform_expression(context, tuple) |> internal.map_return(python.TupleIndex(_, index)) @@ -320,8 +322,7 @@ fn transform_fn( } }) - let function_name = - "_fn_def_" <> { context.next_function_id |> int.to_string } + let function_name = "_fn_def_" <> int.to_string(context.next_function_id) let function = python.Function(function_name, parameters, transform_statement_block(body)) @@ -335,6 +336,23 @@ fn transform_fn( ) } +fn transform_block( + context: internal.TransformerContext, + body: List(glance.Statement), +) { + let function_name = "_fn_block_" <> int.to_string(context.next_block_id) + let function = + python.Function(function_name, [], transform_statement_block(body)) + internal.ExpressionReturn( + context: internal.TransformerContext( + ..context, + next_block_id: context.next_block_id + 1, + ), + statements: [python.FunctionDef(function)], + expression: python.Call(python.Variable(function_name), []), + ) +} + fn transform_pipe( context: internal.TransformerContext, left: glance.Expression, diff --git a/test/expression_test.gleam b/test/expression_test.gleam index 25c25f8..e0e0484 100644 --- a/test/expression_test.gleam +++ b/test/expression_test.gleam @@ -658,3 +658,59 @@ def main(): foo = _fn_def_0", ) } + +pub fn simple_block_test() { + "pub fn main() { + let foo = {1} + }" + |> compiler.compile + |> should.be_ok + |> should.equal( + "from gleam_builtins import * + +def main(): + def _fn_block_0(): + return 1 + foo = _fn_block_0()", + ) +} + +pub fn multiple_block_test() { + "pub fn main() { + let foo = {1} + let bar = {2} + }" + |> compiler.compile + |> should.be_ok + |> should.equal( + "from gleam_builtins import * + +def main(): + def _fn_block_0(): + return 1 + foo = _fn_block_0() + def _fn_block_1(): + return 2 + bar = _fn_block_1()", + ) +} + +pub fn nested_block_test() { + "pub fn main() { + let foo = { + { 1 } + } + }" + |> compiler.compile + |> should.be_ok + |> should.equal( + "from gleam_builtins import * + +def main(): + def _fn_block_0(): + def _fn_block_0(): + return 1 + return _fn_block_0() + foo = _fn_block_0()", + ) +}