Skip to content

Commit

Permalink
Support block case expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
dusty-phillips committed Aug 23, 2024
1 parent 3cf8156 commit 76a8051
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 28 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ are ) in the codebase, as of the last time that I updated this list.
- (EASY) Discard parameters in function arguments are not transformed
- Bitstrings are not supported yet
- case guards are not supported yet
- block case expressions are not supported yet.
- this could be trivially solved by just letting it fall through to the expression arm,
which would generate an extra function, but it should be possible to put those
statements right in the case itself
- Functions as type fields are not supported yet
- debatable whether to make them a `def` right on the class or have the def be defined somewhere and just attach it like other fields
- Fields that are "HoleType" are not supported and I don't even know what that means
Expand Down
5 changes: 1 addition & 4 deletions src/compiler/generator.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import gleam/int
import gleam/list
import gleam/option
import gleam/string_builder.{type StringBuilder}
import pprint
import python_prelude

fn generate_import(import_: python.Import) -> StringBuilder {
Expand Down Expand Up @@ -180,9 +179,7 @@ fn generate_expression(expression: python.Expression) {

fn generate_statement(statement: python.Statement) -> StringBuilder {
case statement {
python.Expression(expression) ->
generate_expression(expression)
|> internal.append_if_not_empty("\n")
python.Expression(expression) -> generate_expression(expression)
python.Return(expression) ->
string_builder.from_string("return ")
|> string_builder.append_builder(generate_expression(expression))
Expand Down
46 changes: 34 additions & 12 deletions src/compiler/internal/transformer/statements.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,24 @@ import pprint
pub fn transform_statement_block(
statements: List(glance.Statement),
) -> List(python.Statement) {
transform_statement_block_with_context(
internal.TransformerContext(
next_function_id: 0,
next_block_id: 0,
next_case_id: 0,
),
statements,
).statements
}

pub fn transform_statement_block_with_context(
context: internal.TransformerContext,
statements: List(glance.Statement),
) -> internal.StatementReturn {
let result =
statements
|> list.fold(
internal.StatementReturn(
context: internal.TransformerContext(
next_function_id: 0,
next_block_id: 0,
next_case_id: 0,
),
statements: [],
),
internal.StatementReturn(context, statements: []),
fn(state, next_statement) {
let result = transform_statement(state.context, next_statement)
internal.StatementReturn(
Expand All @@ -36,8 +43,12 @@ pub fn transform_statement_block(
)
},
)
result.statements
|> internal.transform_last(internal.add_return_if_returnable_expression)

internal.StatementReturn(
..result,
statements: result.statements
|> internal.transform_last(internal.add_return_if_returnable_expression),
)
}

fn transform_statement(
Expand Down Expand Up @@ -401,8 +412,19 @@ fn fold_case_clause(
glance.Clause(guard: option.Some(_), ..) ->
todo as "Case guards not implemented yet"

glance.Clause([pattern_list], option.None, glance.Block(_statements)) -> {
todo as "block case clauses not supported yet"
glance.Clause(pattern_list, option.None, glance.Block(statements)) -> {
let python_pattern = patterns.transform_alternative_patterns(pattern_list)
let statements_result =
transform_statement_block_with_context(state.context, statements)
internal.TransformState(
statements_result.context,
state.statements,
state.item
|> list.prepend(python.MatchCase(
python_pattern,
statements_result.statements,
)),
)
}

glance.Clause(pattern_list, option.None, body) -> {
Expand Down
27 changes: 27 additions & 0 deletions test/case_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,30 @@ def main():
return _fn_case_0((1, 2))",
)
}

pub fn case_block_test() {
"pub fn main() {
case 1 {
1 -> {
let x = 1
let y = 2
x + y
}
}
}
"
|> compiler.compile
|> should.be_ok
|> should.equal(
"from gleam_builtins import *
def main():
def _fn_case_0(_case_subject):
match _case_subject:
case 1:
x = 1
y = 2
return x + y
return _fn_case_0(1)",
)
}
12 changes: 4 additions & 8 deletions test/expression_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ pub fn empty_panic_test() {
"from gleam_builtins import *
def main():
raise GleamPanic(\"panic expression evaluated\")
",
raise GleamPanic(\"panic expression evaluated\")",
)
}

Expand All @@ -196,8 +195,7 @@ pub fn string_panic_test() {
"from gleam_builtins import *
def main():
raise GleamPanic(\"my custom panic\")
",
raise GleamPanic(\"my custom panic\")",
)
}

Expand All @@ -211,8 +209,7 @@ pub fn empty_todo_test() {
"from gleam_builtins import *
def main():
raise NotImplementedError(\"This has not yet been implemented\")
",
raise NotImplementedError(\"This has not yet been implemented\")",
)
}

Expand All @@ -226,8 +223,7 @@ pub fn string_todo_test() {
"from gleam_builtins import *
def main():
raise NotImplementedError(\"much is yet to be done\")
",
raise NotImplementedError(\"much is yet to be done\")",
)
}

Expand Down

0 comments on commit 76a8051

Please sign in to comment.