Skip to content

Add if-then-else statement support#213

Draft
stringhandler wants to merge 1 commit intoBlockstreamResearch:masterfrom
stringhandler:feature/add-if
Draft

Add if-then-else statement support#213
stringhandler wants to merge 1 commit intoBlockstreamResearch:masterfrom
stringhandler:feature/add-if

Conversation

@stringhandler
Copy link

@stringhandler stringhandler commented Feb 9, 2026

Built on #185, so that would need to be merged first.

Addresses #181

@gerau
Copy link
Contributor

gerau commented Feb 9, 2026

Could we make the else expression optional? Maybe we could evaluate a missing else as the unit type (), so this would prevent conflicts when using an if statement in an assignment, for example.

@KyrylR
Copy link
Collaborator

KyrylR commented Feb 10, 2026

#185 is merged, so you can rebase

@stringhandler stringhandler force-pushed the feature/add-if branch 2 times, most recently from 4ec7a0b to bb01ade Compare February 10, 2026 11:25
@stringhandler stringhandler force-pushed the feature/add-if branch 2 times, most recently from 6855146 to ddf467b Compare February 17, 2026 11:11
@stringhandler stringhandler marked this pull request as ready for review February 17, 2026 11:11
@uncomputable
Copy link
Collaborator

This is an if-then-else expression, by the way.

@stringhandler stringhandler changed the title Add if statement support Add if-then-else statement support Feb 17, 2026
@apoelstra
Copy link
Contributor

Sorry for the long delay on this. I thought it would be much harder to review than it was, and I had a big pile of notifications to climb out from under. I should be available closer to real-time from here on out.

In ddf467b:

Are we intentionally allowing expressions that are not blocks? For example tests still pass with this diff:

diff --git a/src/ast.rs b/src/ast.rs
index 3c32866..0ca53ba 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -1733,7 +1733,7 @@ mod test {

     #[test]
     fn test_if_expression_with_complex_arms() {
-        let input = "if false { let x: u8 = 5; x } else { 10 }";
+        let input = "if false { let x: u8 = 5; x } else 10";

         let parsed_expr = parse::Expression::parse_from_str(input).expect("Failed to parse");

This seems okay to me, but it does differ from Rust and if it's intentional we should call it out.

@stringhandler
Copy link
Author

Oh interesting. I thought that was valid in Rust, but it explicitly requires blocks to avoid mistakes. I think it's worth sticking with Rust's rule of requiring brackets. I'll update it

@stringhandler
Copy link
Author

rebased with brace validation

@apoelstra
Copy link
Contributor

Sorry for the delay -- my fuzzer rejected this. But it looks like actually the fuzz failure is on master.

echo 1dVgWywL1VvV1dVAPQAAPTE= | base64 -d > hmm
cargo +nightly fuzz run display_parse_tree hmm
thread '<unnamed>' (2590207) panicked at fuzz/fuzz_targets/display_parse_tree.rs:9:10:
Output of fmt::Display should be parseable: RichError { error: Syntax { expected: ["something else"], label: Some("alias name"), found: Some("fn") }, span: Span { start: 5, end: 7 }, file: None }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

@gerau
Copy link
Contributor

gerau commented Mar 10, 2026

Sorry for the delay -- my fuzzer rejected this. But it looks like actually the fuzz failure is on master.

Seems like an issue with lexer -- it trying to parse type fn = ((),);, but fn is reserved keyword, so it can't be used as alias name. When I wrote the lexer, I tried to imitate rust, and it would reject keywords as identifier name.

@stringhandler stringhandler marked this pull request as draft March 11, 2026 17:26
@stringhandler
Copy link
Author

Converting back to draft for now. I just realised that the Value::from_const_expr will not exclude If. Which means they can be included in witness files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants