diff --git a/birdie_snapshots/block.accepted b/birdie_snapshots/block.accepted new file mode 100644 index 0000000..5177aae --- /dev/null +++ b/birdie_snapshots/block.accepted @@ -0,0 +1,11 @@ +--- +version: 1.4.1 +title: block +file: ./test/trick_test.gleam +test_name: block_test +--- +{ + let a = 1 + let b = 2 + a + b +} diff --git a/birdie_snapshots/block_with_discarded_expression.accepted b/birdie_snapshots/block_with_discarded_expression.accepted new file mode 100644 index 0000000..0bc545a --- /dev/null +++ b/birdie_snapshots/block_with_discarded_expression.accepted @@ -0,0 +1,12 @@ +--- +version: 1.4.1 +title: block_with_discarded_expression +file: ./test/trick_test.gleam +test_name: block_with_discarded_expression_test +--- +{ + let a = 1 + let b = a + 1 + echo b + a * b +} diff --git a/src/trick.gleam b/src/trick.gleam index 4352165..b596183 100644 --- a/src/trick.gleam +++ b/src/trick.gleam @@ -11,6 +11,10 @@ pub opaque type Expression(type_) { Expression(document: Document) } +pub opaque type Statement(type_) { + Statement(document: Document) +} + const width = 80 const indent = 2 @@ -237,9 +241,7 @@ fn add_message(document: Document, message: Document) -> Document { doc.from_string("as "), message, ] - |> doc.concat - |> doc.nest(indent) - |> doc.group + |> grouped } pub fn panic_(message: Option(Expression(String))) -> Expression(a) { @@ -267,9 +269,59 @@ pub fn echo_( Some(message) -> add_message(echo_, message.document) }) } + +pub fn variable( + name: String, + value: Expression(a), + continue: fn(Expression(a)) -> Statement(b), +) -> Statement(b) { + let declaration = + [ + doc.from_string("let "), + doc.from_string(name), + doc.break(" = ", " ="), + value.document, + ] + |> grouped + |> doc.append(doc.line) + + let variable_expression = Expression(doc.from_string(name)) + + let rest = continue(variable_expression) + + Statement(doc.prepend(declaration, to: rest.document)) +} + +fn grouped(documents: List(Document)) -> Document { + documents |> doc.concat |> doc.nest(indent) |> doc.group +} + +pub fn expression(expression: Expression(a)) -> Statement(a) { + Statement(expression.document) +} + +pub fn discard( + statement: Statement(a), + continue: fn() -> Statement(b), +) -> Statement(b) { + let rest = continue() + Statement(doc.concat([statement.document, doc.line, rest.document])) +} + +pub fn block(inner: Statement(a)) -> Expression(a) { + [ + doc.from_string("{"), + doc.line, + inner.document, + ] + |> doc.concat + |> doc.nest(indent) + |> doc.append(doc.line) + |> doc.append(doc.from_string("}")) + |> Expression +} // TODO: // BitString -// Block // Call // Case // FieldAccess @@ -279,4 +331,3 @@ pub fn echo_( // RecordUpdate // Tuple // TupleIndex -// Variable diff --git a/test/trick_test.gleam b/test/trick_test.gleam index 569c5f1..f3b2855 100644 --- a/test/trick_test.gleam +++ b/test/trick_test.gleam @@ -229,3 +229,27 @@ pub fn echo_with_long_message_test() { |> trick.expression_to_string |> birdie.snap("echo_with_long_message") } + +pub fn block_test() { + let block = { + use a <- trick.variable("a", trick.int(1)) + use b <- trick.variable("b", trick.int(2)) + trick.expression(trick.add(a, b)) + } + + block |> trick.block |> trick.expression_to_string |> birdie.snap("block") +} + +pub fn block_with_discarded_expression_test() { + let block = { + use a <- trick.variable("a", trick.int(1)) + use b <- trick.variable("b", trick.add(a, trick.int(1))) + use <- trick.discard(trick.expression(trick.echo_(b, None))) + trick.expression(trick.multiply(a, b)) + } + + block + |> trick.block + |> trick.expression_to_string + |> birdie.snap("block_with_discarded_expression") +}